mirror of https://github.com/yewstack/yew
Move hook API docs to Rustdoc (#2628)
* Move hook API docs to Rustdoc * npm update, fix links and doc tests and callback docs * make doc tests pass * Update packages/yew/src/functional/hooks/use_ref.rs * Update packages/yew/src/functional/hooks/use_ref.rs * Update use_ref.rs
This commit is contained in:
parent
cd5b8a520c
commit
12c9ebb0ea
|
@ -9,11 +9,7 @@ use std::fmt;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
/// Universal callback wrapper.
|
/// Universal callback wrapper.
|
||||||
/// <aside class="warning">
|
///
|
||||||
/// Use callbacks carefully, because if you call one from the `update` loop
|
|
||||||
/// of a `Component` (even from JS) it will delay a message until next.
|
|
||||||
/// Callbacks should be used from JS callbacks or `setTimeout` calls.
|
|
||||||
/// </aside>
|
|
||||||
/// An `Rc` wrapper is used to make it cloneable.
|
/// An `Rc` wrapper is used to make it cloneable.
|
||||||
pub struct Callback<IN, OUT = ()> {
|
pub struct Callback<IN, OUT = ()> {
|
||||||
/// A callback which can be called multiple times
|
/// A callback which can be called multiple times
|
||||||
|
|
|
@ -3,7 +3,8 @@ use std::rc::Rc;
|
||||||
use crate::callback::Callback;
|
use crate::callback::Callback;
|
||||||
use crate::functional::{hook, use_memo};
|
use crate::functional::{hook, use_memo};
|
||||||
|
|
||||||
/// Get a immutable reference to a memoized `Callback`.
|
/// Get a immutable reference to a memoized `Callback`. Its state persists across renders.
|
||||||
|
/// It will be recreated only if any of the dependencies changes value.
|
||||||
///
|
///
|
||||||
/// Memoization means it will only get recreated when provided dependencies update/change.
|
/// Memoization means it will only get recreated when provided dependencies update/change.
|
||||||
/// This is useful when passing callbacks to optimized child components that rely on
|
/// This is useful when passing callbacks to optimized child components that rely on
|
||||||
|
|
|
@ -9,22 +9,57 @@ use crate::functional::{hook, use_component_scope, use_memo, use_state};
|
||||||
/// More information about contexts and how to define and consume them can be found on [Yew Docs](https://yew.rs).
|
/// More information about contexts and how to define and consume them can be found on [Yew Docs](https://yew.rs).
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
/// ```rust
|
|
||||||
/// # use yew::prelude::*;
|
|
||||||
/// # use std::rc::Rc;
|
|
||||||
///
|
///
|
||||||
/// # #[derive(Clone, Debug, PartialEq)]
|
/// ```rust
|
||||||
/// # struct ThemeContext {
|
/// use yew::{ContextProvider, function_component, html, use_context, use_state, Html};
|
||||||
/// # foreground: String,
|
///
|
||||||
/// # background: String,
|
///
|
||||||
/// # }
|
/// /// App theme
|
||||||
/// #[function_component(ThemedButton)]
|
/// #[derive(Clone, Debug, PartialEq)]
|
||||||
/// pub fn themed_button() -> Html {
|
/// struct Theme {
|
||||||
/// let theme = use_context::<Rc<ThemeContext>>().expect("no ctx found");
|
/// foreground: String,
|
||||||
|
/// background: String,
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// /// Main component
|
||||||
|
/// #[function_component]
|
||||||
|
/// pub fn App() -> Html {
|
||||||
|
/// let ctx = use_state(|| Theme {
|
||||||
|
/// foreground: "#000000".to_owned(),
|
||||||
|
/// background: "#eeeeee".to_owned(),
|
||||||
|
/// });
|
||||||
///
|
///
|
||||||
/// html! {
|
/// html! {
|
||||||
/// <button style={format!("background: {}; color: {}", theme.background, theme.foreground)}>
|
/// // `ctx` is type `Rc<UseStateHandle<Theme>>` while we need `Theme`
|
||||||
/// { "Click me" }
|
/// // so we deref it.
|
||||||
|
/// // It derefs to `&Theme`, hence the clone
|
||||||
|
/// <ContextProvider<Theme> context={(*ctx).clone()}>
|
||||||
|
/// // Every child here and their children will have access to this context.
|
||||||
|
/// <Toolbar />
|
||||||
|
/// </ContextProvider<Theme>>
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// /// The toolbar.
|
||||||
|
/// /// This component has access to the context
|
||||||
|
/// #[function_component]
|
||||||
|
/// pub fn Toolbar() -> Html {
|
||||||
|
/// html! {
|
||||||
|
/// <div>
|
||||||
|
/// <ThemedButton />
|
||||||
|
/// </div>
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// /// Button placed in `Toolbar`.
|
||||||
|
/// /// As this component is a child of `ThemeContextProvider` in the component tree, it also has access to the context.
|
||||||
|
/// #[function_component]
|
||||||
|
/// pub fn ThemedButton() -> Html {
|
||||||
|
/// let theme = use_context::<Theme>().expect("no ctx found");
|
||||||
|
///
|
||||||
|
/// html! {
|
||||||
|
/// <button style={format!("background: {}; color: {};", theme.background, theme.foreground)}>
|
||||||
|
/// { "Click me!" }
|
||||||
/// </button>
|
/// </button>
|
||||||
/// }
|
/// }
|
||||||
/// }
|
/// }
|
||||||
|
|
|
@ -108,13 +108,16 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This hook is used for hooking into the component's lifecycle.
|
/// `use_effect` is used for hooking into the component's lifecycle and creating side effects.
|
||||||
|
///
|
||||||
|
/// The callback is called every time after the component's render has finished.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # use yew::prelude::*;
|
/// use yew::prelude::*;
|
||||||
/// # use std::rc::Rc;
|
/// # use std::rc::Rc;
|
||||||
/// #
|
///
|
||||||
/// #[function_component(UseEffect)]
|
/// #[function_component(UseEffect)]
|
||||||
/// fn effect() -> Html {
|
/// fn effect() -> Html {
|
||||||
/// let counter = use_state(|| 0);
|
/// let counter = use_state(|| 0);
|
||||||
|
@ -151,7 +154,85 @@ where
|
||||||
///
|
///
|
||||||
/// Whenever the dependencies are changed, the effect callback is called again.
|
/// Whenever the dependencies are changed, the effect callback is called again.
|
||||||
/// To detect changes, dependencies must implement `PartialEq`.
|
/// To detect changes, dependencies must implement `PartialEq`.
|
||||||
/// Note that the destructor also runs when dependencies change.
|
///
|
||||||
|
/// # Note
|
||||||
|
/// The destructor also runs when dependencies change.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use yew::{function_component, html, Html, Properties, use_effect_with_deps};
|
||||||
|
/// # use gloo::console::log;
|
||||||
|
///
|
||||||
|
/// #[derive(Properties, PartialEq)]
|
||||||
|
/// pub struct Props {
|
||||||
|
/// pub is_loading: bool,
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// #[function_component]
|
||||||
|
/// fn HelloWorld(props: &Props) -> Html {
|
||||||
|
/// let is_loading = props.is_loading.clone();
|
||||||
|
///
|
||||||
|
/// use_effect_with_deps(
|
||||||
|
/// move |_| {
|
||||||
|
/// log!(" Is loading prop changed!");
|
||||||
|
/// || ()
|
||||||
|
/// },
|
||||||
|
/// is_loading,
|
||||||
|
/// );
|
||||||
|
///
|
||||||
|
/// html! { <>{"Am I loading? - "}{is_loading}</> }
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// # Tips
|
||||||
|
///
|
||||||
|
/// ## Only on first render
|
||||||
|
///
|
||||||
|
/// Provide a empty tuple `()` as dependencies when you need to do something only on the first render
|
||||||
|
/// of a component.
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use yew::{function_component, html, Html, use_effect_with_deps};
|
||||||
|
/// # use gloo::console::log;
|
||||||
|
///
|
||||||
|
/// #[function_component]
|
||||||
|
/// fn HelloWorld() -> Html {
|
||||||
|
///
|
||||||
|
/// use_effect_with_deps(
|
||||||
|
/// move |_| {
|
||||||
|
/// log!("I got rendered, yay!");
|
||||||
|
/// || ()
|
||||||
|
/// },
|
||||||
|
/// (),
|
||||||
|
/// );
|
||||||
|
///
|
||||||
|
/// html! { "Hello" }
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// ## On destructing or last render
|
||||||
|
///
|
||||||
|
/// Use [Only on first render](#only-on-first-render) but put the code in the cleanup function.
|
||||||
|
/// It will only get called when the component is removed from view / gets destroyed.
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use yew::{function_component, html, Html, use_effect_with_deps};
|
||||||
|
/// # use gloo::console::log;
|
||||||
|
///
|
||||||
|
/// #[function_component]
|
||||||
|
/// fn HelloWorld() -> Html {
|
||||||
|
/// use_effect_with_deps(
|
||||||
|
/// move |_| {
|
||||||
|
/// || {
|
||||||
|
/// log!("Noo dont kill me, ahhh!");
|
||||||
|
/// }
|
||||||
|
/// },
|
||||||
|
/// (),
|
||||||
|
/// );
|
||||||
|
/// html! { "Hello" }
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
#[hook]
|
#[hook]
|
||||||
pub fn use_effect_with_deps<T, F, D>(f: F, deps: T)
|
pub fn use_effect_with_deps<T, F, D>(f: F, deps: T)
|
||||||
where
|
where
|
||||||
|
|
|
@ -31,12 +31,22 @@ impl UseForceUpdate {
|
||||||
|
|
||||||
/// This hook is used to manually force a function component to re-render.
|
/// This hook is used to manually force a function component to re-render.
|
||||||
///
|
///
|
||||||
|
/// # Note
|
||||||
|
///
|
||||||
|
/// Often, using this hook means that you're doing something wrong.
|
||||||
/// Try to use more specialized hooks, such as [`use_state`] and [`use_reducer`].
|
/// Try to use more specialized hooks, such as [`use_state`] and [`use_reducer`].
|
||||||
/// This hook should only be used when your component depends on external state where you
|
/// This hook should only be used when your component depends on external state where you
|
||||||
/// can't subscribe to changes, or as a low-level primitive to enable such a subscription-based
|
/// can't subscribe to changes, or as a low-level primitive to enable such a subscription-based
|
||||||
/// approach.
|
/// approach.
|
||||||
///
|
///
|
||||||
/// For example, a large externally managed cache, such as a app-wide cache for GraphQL data
|
/// # Use-case
|
||||||
|
///
|
||||||
|
/// Use this hook when wrapping an API that doesn't expose precise subscription events for fetched data.
|
||||||
|
/// You could then, at some point, invalidate your local cache of the fetched data and trigger a re-render
|
||||||
|
/// to let the normal render flow of components tell you again which data to fetch, and repopulate the
|
||||||
|
/// cache accordingly.
|
||||||
|
///
|
||||||
|
/// A large externally managed cache, such as a app-wide cache for GraphQL data
|
||||||
/// should not rerender every component whenever new data arrives, but only those where a query
|
/// should not rerender every component whenever new data arrives, but only those where a query
|
||||||
/// changed.
|
/// changed.
|
||||||
///
|
///
|
||||||
|
@ -45,11 +55,11 @@ impl UseForceUpdate {
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
/// This example implements a silly, manually updated display of the current time. The component
|
/// This example implements a silly, manually updated display of the current time. The component
|
||||||
/// is rerendered every time the button is clicked. You should usually use a timeout and `use_state`
|
/// is re-rendered every time the button is clicked. You should usually use a timeout and `use_state`
|
||||||
/// to automatically trigger a re-render every second without having to use this hook.
|
/// to automatically trigger a re-render every second without having to use this hook.
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # use yew::prelude::*;
|
/// use yew::prelude::*;
|
||||||
///
|
///
|
||||||
/// #[function_component]
|
/// #[function_component]
|
||||||
/// fn ManuallyUpdatedDate() -> Html {
|
/// fn ManuallyUpdatedDate() -> Html {
|
||||||
|
|
|
@ -42,11 +42,14 @@ where
|
||||||
///
|
///
|
||||||
/// Memoization means it will only get recalculated when provided dependencies update/change.
|
/// Memoization means it will only get recalculated when provided dependencies update/change.
|
||||||
///
|
///
|
||||||
|
/// It can be useful for keeping things in scope for the lifetime of the component,
|
||||||
|
/// so long as you don't store a clone of the resulting `Rc` anywhere that outlives the component.
|
||||||
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # use yew::prelude::*;
|
/// use yew::prelude::*;
|
||||||
/// #
|
///
|
||||||
/// #[derive(PartialEq, Properties)]
|
/// #[derive(PartialEq, Properties)]
|
||||||
/// pub struct Props {
|
/// pub struct Props {
|
||||||
/// pub step: usize,
|
/// pub step: usize,
|
||||||
|
|
|
@ -222,6 +222,13 @@ where
|
||||||
/// The state is expected to implement the [`Reducible`] trait which provides an `Action` type and a reducer
|
/// The state is expected to implement the [`Reducible`] trait which provides an `Action` type and a reducer
|
||||||
/// function.
|
/// function.
|
||||||
///
|
///
|
||||||
|
/// The state object returned by the initial state function is required to
|
||||||
|
/// implement a `Reducible` trait which defines the associated `Action` type and a
|
||||||
|
/// reducer function.
|
||||||
|
///
|
||||||
|
/// This hook will always trigger a re-render upon receiving an action. See
|
||||||
|
/// [`use_reducer_eq`] if you want the component to only re-render when the state changes.
|
||||||
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # use yew::prelude::*;
|
/// # use yew::prelude::*;
|
||||||
|
@ -284,6 +291,21 @@ where
|
||||||
/// }
|
/// }
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
///
|
||||||
|
/// # Tip
|
||||||
|
///
|
||||||
|
/// The dispatch function is guaranteed to be the same across the entire
|
||||||
|
/// component lifecycle. You can safely omit the `UseReducerHandle` from the
|
||||||
|
/// dependents of `use_effect_with_deps` if you only intend to dispatch
|
||||||
|
/// values from within the hooks.
|
||||||
|
///
|
||||||
|
/// # Caution
|
||||||
|
///
|
||||||
|
/// The value held in the handle will reflect the value of at the time the
|
||||||
|
/// handle is returned by the `use_reducer`. It is possible that the handle does
|
||||||
|
/// not dereference to an up to date value if you are moving it into a
|
||||||
|
/// `use_effect_with_deps` hook. You can register the
|
||||||
|
/// state to the dependents so the hook can be updated when the value changes.
|
||||||
#[hook]
|
#[hook]
|
||||||
pub fn use_reducer<T, F>(init_fn: F) -> UseReducerHandle<T>
|
pub fn use_reducer<T, F>(init_fn: F) -> UseReducerHandle<T>
|
||||||
where
|
where
|
||||||
|
|
|
@ -24,12 +24,12 @@ impl<T: 'static, F: FnOnce() -> T> Hook for UseMutRef<F> {
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # use yew::prelude::*;
|
/// use yew::prelude::*;
|
||||||
/// # use web_sys::HtmlInputElement;
|
/// use web_sys::HtmlInputElement;
|
||||||
/// # use std::rc::Rc;
|
/// use std::rc::Rc;
|
||||||
/// # use std::cell::RefCell;
|
/// use std::cell::RefCell;
|
||||||
/// # use std::ops::{Deref, DerefMut};
|
/// use std::ops::{Deref, DerefMut};
|
||||||
/// #
|
///
|
||||||
/// #[function_component(UseRef)]
|
/// #[function_component(UseRef)]
|
||||||
/// fn ref_hook() -> Html {
|
/// fn ref_hook() -> Html {
|
||||||
/// let message = use_state(|| "".to_string());
|
/// let message = use_state(|| "".to_string());
|
||||||
|
@ -72,16 +72,15 @@ where
|
||||||
/// This hook is used for obtaining a [`NodeRef`].
|
/// This hook is used for obtaining a [`NodeRef`].
|
||||||
/// It persists across renders.
|
/// It persists across renders.
|
||||||
///
|
///
|
||||||
/// It is important to note that you do not get notified of state changes.
|
/// The `ref` attribute can be used to attach the [`NodeRef`] to an HTML element. In callbacks,
|
||||||
|
/// you can then get the DOM `Element` that the `ref` is attached to.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # use wasm_bindgen::{prelude::Closure, JsCast};
|
/// use wasm_bindgen::{prelude::Closure, JsCast};
|
||||||
/// # use yew::{
|
/// use yew::{function_component, html, use_effect_with_deps, use_node_ref, Html};
|
||||||
/// # function_component, html, use_effect_with_deps, use_node_ref,
|
/// use web_sys::{Event, HtmlElement};
|
||||||
/// # Html,
|
|
||||||
/// # };
|
|
||||||
/// # use web_sys::{Event, HtmlElement};
|
|
||||||
///
|
///
|
||||||
/// #[function_component(UseNodeRef)]
|
/// #[function_component(UseNodeRef)]
|
||||||
/// pub fn node_ref_hook() -> Html {
|
/// pub fn node_ref_hook() -> Html {
|
||||||
|
@ -124,8 +123,13 @@ where
|
||||||
/// </div>
|
/// </div>
|
||||||
/// }
|
/// }
|
||||||
/// }
|
/// }
|
||||||
///
|
|
||||||
/// ```
|
/// ```
|
||||||
|
///
|
||||||
|
/// # Tip
|
||||||
|
///
|
||||||
|
/// When conditionally rendering elements you can use `NodeRef` in conjunction with `use_effect_with_deps`
|
||||||
|
/// to perform actions each time an element is rendered and just before the component where the hook is used in is going to be removed from the
|
||||||
|
/// DOM.
|
||||||
#[hook]
|
#[hook]
|
||||||
pub fn use_node_ref() -> NodeRef {
|
pub fn use_node_ref() -> NodeRef {
|
||||||
(*use_state(NodeRef::default)).clone()
|
(*use_state(NodeRef::default)).clone()
|
||||||
|
|
|
@ -27,11 +27,16 @@ where
|
||||||
|
|
||||||
/// This hook is used to manage state in a function component.
|
/// This hook is used to manage state in a function component.
|
||||||
///
|
///
|
||||||
|
/// This hook will always trigger a re-render upon receiving a new state. See [`use_state_eq`]
|
||||||
|
/// if you want the component to only re-render when the new state compares unequal
|
||||||
|
/// to the existing one.
|
||||||
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # use yew::prelude::*;
|
/// use yew::prelude::*;
|
||||||
/// # use std::rc::Rc;
|
/// # use std::rc::Rc;
|
||||||
/// #
|
///
|
||||||
/// #[function_component(UseState)]
|
/// #[function_component(UseState)]
|
||||||
/// fn state() -> Html {
|
/// fn state() -> Html {
|
||||||
/// let counter = use_state(|| 0);
|
/// let counter = use_state(|| 0);
|
||||||
|
@ -52,6 +57,21 @@ where
|
||||||
/// }
|
/// }
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
///
|
||||||
|
/// # Caution
|
||||||
|
///
|
||||||
|
/// The value held in the handle will reflect the value of at the time the
|
||||||
|
/// handle is returned by the `use_reducer`. It is possible that the handle does
|
||||||
|
/// not dereference to an up to date value if you are moving it into a
|
||||||
|
/// `use_effect_with_deps` hook. You can register the
|
||||||
|
/// state to the dependents so the hook can be updated when the value changes.
|
||||||
|
///
|
||||||
|
/// # Tip
|
||||||
|
///
|
||||||
|
/// The setter function is guaranteed to be the same across the entire
|
||||||
|
/// component lifecycle. You can safely omit the `UseStateHandle` from the
|
||||||
|
/// dependents of `use_effect_with_deps` if you only intend to set
|
||||||
|
/// values from within the hook.
|
||||||
#[hook]
|
#[hook]
|
||||||
pub fn use_state<T, F>(init_fn: F) -> UseStateHandle<T>
|
pub fn use_state<T, F>(init_fn: F) -> UseStateHandle<T>
|
||||||
where
|
where
|
||||||
|
|
|
@ -134,7 +134,7 @@ fn App() -> Html {
|
||||||
#### Function components
|
#### Function components
|
||||||
|
|
||||||
`use_context` hook is used to consume contexts in function components.
|
`use_context` hook is used to consume contexts in function components.
|
||||||
See [docs for use_context](function-components/hooks/use-context.mdx) to learn more.
|
See [docs for use_context](https://yew-rs-api.web.app/next/yew/functional/fn.use_context.html) to learn more.
|
||||||
|
|
||||||
#### Struct components
|
#### Struct components
|
||||||
|
|
||||||
|
@ -164,7 +164,7 @@ You should refactor the `Layout` component to take children as props and display
|
||||||
|
|
||||||
Because of Rust's ownership rules, a context cannot have a method that takes `&mut self` that can be called by children.
|
Because of Rust's ownership rules, a context cannot have a method that takes `&mut self` that can be called by children.
|
||||||
In order to mutate a context's value, we must combine it with a reducer. This is done by using the
|
In order to mutate a context's value, we must combine it with a reducer. This is done by using the
|
||||||
[`use_reducer`](./function-components/hooks/use-reducer.mdx) hook.
|
[`use_reducer`](https://yew-rs-api.web.app/next/yew/functional/fn.use_reducer.html) hook.
|
||||||
|
|
||||||
The [contexts example](https://github.com/yewstack/yew/tree/master/examples/contexts) demonstrates mutable contexts
|
The [contexts example](https://github.com/yewstack/yew/tree/master/examples/contexts) demonstrates mutable contexts
|
||||||
with the help of contexts
|
with the help of contexts
|
||||||
|
|
|
@ -25,18 +25,20 @@ These rules are enforced by either compile time or run-time errors.
|
||||||
|
|
||||||
Yew comes with the following predefined Hooks:
|
Yew comes with the following predefined Hooks:
|
||||||
|
|
||||||
- [`use_state`](./use-state.mdx)
|
- `use_state`
|
||||||
- [`use_state_eq`](./use-state.mdx#use_state_eq)
|
- `use_state_eq`
|
||||||
- [`use_memo`](./use-memo.mdx)
|
- `use_memo`
|
||||||
- [`use_callback`](./use-callback.mdx)
|
- `use_callback`
|
||||||
- [`use_mut_ref`](./use-mut-ref.mdx)
|
- `use_mut_ref`
|
||||||
- [`use_node_ref`](./use-node-ref.mdx)
|
- `use_node_ref`
|
||||||
- [`use_reducer`](./use-reducer.mdx)
|
- `use_reducer`
|
||||||
- [`use_reducer_eq`](./use-reducer.mdx#use_reducer_eq)
|
- `use_reducer_eq`
|
||||||
- [`use_effect`](./use-effect.mdx)
|
- `use_effect`
|
||||||
- [`use_effect_with_deps`](./use-effect.mdx#use_effect_with_deps)
|
- `use_effect_with_deps`
|
||||||
- [`use_context`](./use-context.mdx)
|
- `use_context`
|
||||||
- [`use_force_update`](./use-force-update.mdx)
|
- `use_force_update`
|
||||||
|
|
||||||
|
The documentation for these hooks can be found in the [Yew API docs](https://yew-rs-api.web.app/next/yew/functional/)
|
||||||
|
|
||||||
### Custom Hooks
|
### Custom Hooks
|
||||||
|
|
||||||
|
|
|
@ -1,67 +0,0 @@
|
||||||
---
|
|
||||||
title: 'use_callback'
|
|
||||||
---
|
|
||||||
|
|
||||||
`use_callback` is used for obtaining an immutable reference to a memoized `Callback`.
|
|
||||||
Its state persists across renders.
|
|
||||||
It will be recreated only if any of the dependencies changes value.
|
|
||||||
|
|
||||||
`use_callback` can be useful when passing callbacks to optimized child components that rely on
|
|
||||||
PartialEq to prevent unnecessary renders.
|
|
||||||
|
|
||||||
```rust
|
|
||||||
use yew::prelude::*;
|
|
||||||
|
|
||||||
#[derive(Properties, PartialEq)]
|
|
||||||
pub struct Props {
|
|
||||||
pub callback: Callback<String, String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[function_component(MyComponent)]
|
|
||||||
fn my_component(props: &Props) -> Html {
|
|
||||||
let greeting = props.callback.emit("Yew".to_string());
|
|
||||||
|
|
||||||
html! {
|
|
||||||
<>{ &greeting }</>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[function_component(UseCallback)]
|
|
||||||
fn callback() -> Html {
|
|
||||||
let counter = use_state(|| 0);
|
|
||||||
let onclick = {
|
|
||||||
let counter = counter.clone();
|
|
||||||
Callback::from(move |_| counter.set(*counter + 1))
|
|
||||||
};
|
|
||||||
|
|
||||||
// This callback depends on (), so it's created only once, then MyComponent
|
|
||||||
// will be rendered only once even when you click the button mutiple times.
|
|
||||||
let callback = use_callback(
|
|
||||||
move |name, _| format!("Hello, {}!", name),
|
|
||||||
()
|
|
||||||
);
|
|
||||||
|
|
||||||
// It can also be used for events, this callback depends on `counter`.
|
|
||||||
let oncallback = {
|
|
||||||
let counter = counter.clone();
|
|
||||||
use_callback(
|
|
||||||
move |_e, counter| {
|
|
||||||
let _ = **counter;
|
|
||||||
},
|
|
||||||
counter
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
html! {
|
|
||||||
<div>
|
|
||||||
<button {onclick}>{ "Increment value" }</button>
|
|
||||||
<button onclick={oncallback}>{ "Callback" }</button>
|
|
||||||
<p>
|
|
||||||
<b>{ "Current value: " }</b>
|
|
||||||
{ *counter }
|
|
||||||
</p>
|
|
||||||
<MyComponent {callback} />
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
|
@ -1,63 +0,0 @@
|
||||||
---
|
|
||||||
title: 'use_context'
|
|
||||||
---
|
|
||||||
|
|
||||||
`use_context` is used for consuming [contexts](../../contexts.mdx) in function components.
|
|
||||||
|
|
||||||
## Example
|
|
||||||
|
|
||||||
```rust
|
|
||||||
use yew::{ContextProvider, function_component, html, use_context, use_state, Html};
|
|
||||||
|
|
||||||
|
|
||||||
/// App theme
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
|
||||||
struct Theme {
|
|
||||||
foreground: String,
|
|
||||||
background: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Main component
|
|
||||||
#[function_component]
|
|
||||||
pub fn App() -> Html {
|
|
||||||
let ctx = use_state(|| Theme {
|
|
||||||
foreground: "#000000".to_owned(),
|
|
||||||
background: "#eeeeee".to_owned(),
|
|
||||||
});
|
|
||||||
|
|
||||||
html! {
|
|
||||||
// `ctx` is type `Rc<UseStateHandle<Theme>>` while we need `Theme`
|
|
||||||
// so we deref it.
|
|
||||||
// It derefs to `&Theme`, hence the clone
|
|
||||||
<ContextProvider<Theme> context={(*ctx).clone()}>
|
|
||||||
// Every child here and their children will have access to this context.
|
|
||||||
<Toolbar />
|
|
||||||
</ContextProvider<Theme>>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The toolbar.
|
|
||||||
/// This component has access to the context
|
|
||||||
#[function_component]
|
|
||||||
pub fn Toolbar() -> Html {
|
|
||||||
html! {
|
|
||||||
<div>
|
|
||||||
<ThemedButton />
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Button placed in `Toolbar`.
|
|
||||||
/// As this component is a child of `ThemeContextProvider` in the component tree, it also has access to the context.
|
|
||||||
#[function_component]
|
|
||||||
pub fn ThemedButton() -> Html {
|
|
||||||
//highlight-next-line
|
|
||||||
let theme = use_context::<Theme>().expect("no ctx found");
|
|
||||||
|
|
||||||
html! {
|
|
||||||
<button style={format!("background: {}; color: {};", theme.background, theme.foreground)}>
|
|
||||||
{ "Click me!" }
|
|
||||||
</button>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
|
@ -1,126 +0,0 @@
|
||||||
---
|
|
||||||
title: 'use_effect'
|
|
||||||
---
|
|
||||||
|
|
||||||
`use_effect` is used for hooking into the component's lifecycle and creating side-effects.
|
|
||||||
|
|
||||||
It takes a function which is called every time after the component's render has finished.
|
|
||||||
|
|
||||||
The input function has to return a closure - a cleanup function, which is called right
|
|
||||||
before starting a new render or when the component unmounts.
|
|
||||||
|
|
||||||
## Example
|
|
||||||
|
|
||||||
```rust
|
|
||||||
use yew::{Callback, function_component, html, use_effect, use_state, Html};
|
|
||||||
|
|
||||||
#[function_component]
|
|
||||||
fn EffectExample() -> Html {
|
|
||||||
let counter = use_state(|| 0);
|
|
||||||
|
|
||||||
{
|
|
||||||
let counter = counter.clone();
|
|
||||||
use_effect(move || {
|
|
||||||
// Make a call to DOM API after component is rendered
|
|
||||||
gloo::utils::document().set_title(&format!("You clicked {} times", *counter));
|
|
||||||
|
|
||||||
// Perform the cleanup
|
|
||||||
|| gloo::utils::document().set_title("You clicked 0 times")
|
|
||||||
});
|
|
||||||
}
|
|
||||||
let onclick = {
|
|
||||||
let counter = counter.clone();
|
|
||||||
Callback::from(move |_| counter.set(*counter + 1))
|
|
||||||
};
|
|
||||||
|
|
||||||
html! {
|
|
||||||
<button {onclick}>{ format!("Increment to {}", *counter) }</button>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## `use_effect_with_deps`
|
|
||||||
|
|
||||||
`use_effect_with_deps` is a more enhanced version of [`use_effect`](#use_effect).
|
|
||||||
|
|
||||||
It takes a second argument - dependencies. The effect is only executed - and the
|
|
||||||
old effect cleaned up - when the dependencies change compared to the previous call.
|
|
||||||
|
|
||||||
:::note
|
|
||||||
|
|
||||||
`dependencies` must implement `PartialEq`.
|
|
||||||
|
|
||||||
:::
|
|
||||||
|
|
||||||
```rust
|
|
||||||
use yew::{function_component, html, Html, Properties, use_effect_with_deps};
|
|
||||||
|
|
||||||
#[derive(Properties, PartialEq)]
|
|
||||||
pub struct Props {
|
|
||||||
pub is_loading: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[function_component]
|
|
||||||
fn HelloWorld(props: &Props) -> Html {
|
|
||||||
let is_loading = props.is_loading.clone();
|
|
||||||
|
|
||||||
use_effect_with_deps(
|
|
||||||
move |_| {
|
|
||||||
web_sys::console::log_1(&" Is loading prop changed!".into());
|
|
||||||
|| ()
|
|
||||||
},
|
|
||||||
// highlight-next-line
|
|
||||||
is_loading,
|
|
||||||
);
|
|
||||||
|
|
||||||
html! { <>{"Am I loading? - "}{is_loading}</> }
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Tips
|
|
||||||
|
|
||||||
### Only on first render {#only-on-first-render}
|
|
||||||
|
|
||||||
Provide a empty tuple `()` as dependencies when you need to do something only on the first render
|
|
||||||
of a component.
|
|
||||||
|
|
||||||
```rust
|
|
||||||
use yew::{function_component, html, Html, use_effect_with_deps};
|
|
||||||
|
|
||||||
#[function_component]
|
|
||||||
fn HelloWorld() -> Html {
|
|
||||||
|
|
||||||
use_effect_with_deps(
|
|
||||||
move |_| {
|
|
||||||
web_sys::console::log_1(&"I got rendered, yay!".into());
|
|
||||||
|| ()
|
|
||||||
},
|
|
||||||
// highlight-next-line
|
|
||||||
(),
|
|
||||||
);
|
|
||||||
|
|
||||||
html! { "Hello" }
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### On destructing or last render
|
|
||||||
|
|
||||||
Use [Only on first render](#only-on-first-render) but put the code in the cleanup function.
|
|
||||||
It will only get called when the component is removed from view / gets destroyed.
|
|
||||||
|
|
||||||
```rust
|
|
||||||
use yew::{function_component, html, Html, use_effect_with_deps};
|
|
||||||
|
|
||||||
#[function_component]
|
|
||||||
fn HelloWorld() -> Html {
|
|
||||||
use_effect_with_deps(
|
|
||||||
move |_| {
|
|
||||||
|| {
|
|
||||||
web_sys::console::log_1(&"Noo dont kill me, ahhh!".into());
|
|
||||||
}
|
|
||||||
},
|
|
||||||
(),
|
|
||||||
);
|
|
||||||
html! { "Hello" }
|
|
||||||
}
|
|
||||||
```
|
|
|
@ -1,17 +0,0 @@
|
||||||
---
|
|
||||||
title: 'use_force_update'
|
|
||||||
---
|
|
||||||
|
|
||||||
`use_force_update` is a low-level hook specialized to triggering a re-render of a function component.
|
|
||||||
Usually, this re-render is triggered automatically by the hook holding your data, for example when
|
|
||||||
changing the data in a handle returned from [`use_state`](./use-state).
|
|
||||||
|
|
||||||
:::caution
|
|
||||||
Often, using this hook means you are doing something wrong and should use one of the other hooks,
|
|
||||||
for example [`use_reducer`](./use-reducer) is another great way to track changing data.
|
|
||||||
:::
|
|
||||||
|
|
||||||
Use this hook when wrapping an API that doesn't expose precise subscription events for fetched data.
|
|
||||||
You could then, at some point, invalidate your local cache of the fetched data and trigger a re-render
|
|
||||||
to let the normal render flow of components tell you again which data to fetch, and repopulate the
|
|
||||||
cache accordingly.
|
|
|
@ -1,34 +0,0 @@
|
||||||
---
|
|
||||||
title: 'use_memo'
|
|
||||||
---
|
|
||||||
|
|
||||||
`use_memo` is used for obtaining an immutable reference to a memoized value.
|
|
||||||
Its state persists across renders.
|
|
||||||
Its value will be recalculated only if any of the dependencies changes value.
|
|
||||||
|
|
||||||
`use_memo` can be useful for keeping things in scope for the lifetime of the component, so long as
|
|
||||||
you don't store a clone of the resulting `Rc` anywhere that outlives the component.
|
|
||||||
|
|
||||||
```rust
|
|
||||||
use yew::{function_component, html, use_memo, use_state, Callback, Html, Properties};
|
|
||||||
|
|
||||||
#[derive(PartialEq, Properties)]
|
|
||||||
pub struct Props {
|
|
||||||
pub step: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[function_component(UseMemo)]
|
|
||||||
fn ref_hook(props: &Props) -> Html {
|
|
||||||
// Will only get recalculated if `props.step` value changes
|
|
||||||
let message = use_memo(
|
|
||||||
|step| format!("{}. Do Some Expensive Calculation", step),
|
|
||||||
props.step
|
|
||||||
);
|
|
||||||
|
|
||||||
html! {
|
|
||||||
<div>
|
|
||||||
<span>{ (*message).clone() }</span>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
|
@ -1,55 +0,0 @@
|
||||||
---
|
|
||||||
title: 'use_mut_ref'
|
|
||||||
---
|
|
||||||
|
|
||||||
`use_mut_ref` is used for obtaining a mutable reference to a value.
|
|
||||||
Its state persists across renders.
|
|
||||||
|
|
||||||
It is important to note that you do not get notified of state changes.
|
|
||||||
If you need the component to be re-rendered on state change, consider using [`use_state`](./use-state).
|
|
||||||
|
|
||||||
## Example
|
|
||||||
|
|
||||||
Here you can see we count `message_count` as that number is not used in `Html` and thus does not need to cause a rerender.
|
|
||||||
|
|
||||||
```rust
|
|
||||||
use web_sys::HtmlInputElement;
|
|
||||||
use yew::{
|
|
||||||
events::Event,
|
|
||||||
function_component, html, use_mut_ref, use_state,
|
|
||||||
Callback, TargetCast,
|
|
||||||
Html,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[function_component]
|
|
||||||
fn MutRefExample() -> Html {
|
|
||||||
let message = use_state(|| "".to_string());
|
|
||||||
let message_count = use_mut_ref(|| 0);
|
|
||||||
|
|
||||||
let onclick = Callback::from(move |_| {
|
|
||||||
let window = gloo::utils::window();
|
|
||||||
|
|
||||||
if *message_count.borrow_mut() > 3 {
|
|
||||||
window.alert_with_message("Message limit reached").unwrap();
|
|
||||||
} else {
|
|
||||||
*message_count.borrow_mut() += 1;
|
|
||||||
window.alert_with_message("Message sent").unwrap();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let onchange = {
|
|
||||||
let message = message.clone();
|
|
||||||
Callback::from(move |e: Event| {
|
|
||||||
let input: HtmlInputElement = e.target_unchecked_into();
|
|
||||||
message.set(input.value());
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
html! {
|
|
||||||
<div>
|
|
||||||
<input {onchange} value={(*message).clone()} />
|
|
||||||
<button {onclick}>{ "Send" }</button>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
|
@ -1,54 +0,0 @@
|
||||||
---
|
|
||||||
title: 'use_node_ref'
|
|
||||||
---
|
|
||||||
|
|
||||||
`use_node_ref` is used for maintaining a reference to a DOM element represented as a
|
|
||||||
[`NodeRef`](../node-refs.mdx). It also persists across renders.
|
|
||||||
|
|
||||||
The `ref` attribute can be used to attach the `NodeRef` to an HTML element. In callbacks,
|
|
||||||
you can then get the DOM `Element` that the ref is attached to.
|
|
||||||
|
|
||||||
## Example
|
|
||||||
|
|
||||||
```rust
|
|
||||||
use web_sys::HtmlInputElement;
|
|
||||||
use yew::{
|
|
||||||
function_component, functional::*, html,
|
|
||||||
NodeRef, Html
|
|
||||||
};
|
|
||||||
|
|
||||||
#[function_component(UseRef)]
|
|
||||||
pub fn ref_hook() -> Html {
|
|
||||||
// highlight-next-line
|
|
||||||
let input_ref = use_node_ref();
|
|
||||||
let value = use_state(|| 25_f64);
|
|
||||||
|
|
||||||
let onclick = {
|
|
||||||
let input_ref = input_ref.clone();
|
|
||||||
let value = value.clone();
|
|
||||||
move |_| {
|
|
||||||
// highlight-start
|
|
||||||
if let Some(input) = input_ref.cast::<HtmlInputElement>() {
|
|
||||||
value.set(*value + input.value_as_number());
|
|
||||||
}
|
|
||||||
// highlight-end
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
html! {
|
|
||||||
<div>
|
|
||||||
// highlight-next-line
|
|
||||||
<input ref={input_ref} type="number" />
|
|
||||||
<button {onclick}>{ format!("Add input to {}", *value) }</button>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
:::tip Advanced tip
|
|
||||||
|
|
||||||
When conditionally rendering elements you can use `NodeRef` in conjunction with `use_effect_with_deps`
|
|
||||||
to perform actions each time an element is rendered and just before its going to be removed from the
|
|
||||||
DOM.
|
|
||||||
|
|
||||||
:::
|
|
|
@ -1,109 +0,0 @@
|
||||||
---
|
|
||||||
title: 'use_reducer'
|
|
||||||
---
|
|
||||||
|
|
||||||
`use_reducer` is an alternative to [`use_state`](./use-state). It is used to handle more complex component's state.
|
|
||||||
|
|
||||||
It accepts an initializer function and returns a `UseReducerHandle` that dereferences to the state,
|
|
||||||
and a dispatch function.
|
|
||||||
The dispatch function takes one argument of type `Action`. When called, the action and current value
|
|
||||||
are passed to the reducer function which computes a new state that is returned,
|
|
||||||
and the component is re-rendered.
|
|
||||||
|
|
||||||
:::tip Advanced tip
|
|
||||||
|
|
||||||
The dispatch function is guaranteed to be the same across the entire
|
|
||||||
component lifecycle. You can safely omit the `UseReducerHandle` from the
|
|
||||||
dependents of `use_effect_with_deps` if you only intend to dispatch
|
|
||||||
values from within the hooks.
|
|
||||||
|
|
||||||
:::
|
|
||||||
|
|
||||||
The state object returned by the initial state function is required to
|
|
||||||
implement a `Reducible` trait which defines the associated `Action` type and a
|
|
||||||
reducer function.
|
|
||||||
|
|
||||||
This hook will always trigger a re-render upon receiving an action. See
|
|
||||||
[`use_reducer_eq`](#use_reducer_eq) if you want the component to only
|
|
||||||
re-render when the state changes.
|
|
||||||
|
|
||||||
## Example
|
|
||||||
|
|
||||||
```rust
|
|
||||||
use yew::prelude::*;
|
|
||||||
use std::rc::Rc;
|
|
||||||
|
|
||||||
/// reducer's Action
|
|
||||||
enum CounterAction {
|
|
||||||
Double,
|
|
||||||
Square,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// reducer's State
|
|
||||||
struct CounterState {
|
|
||||||
counter: i32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for CounterState {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self { counter: 1 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Reducible for CounterState {
|
|
||||||
/// Reducer Action Type
|
|
||||||
type Action = CounterAction;
|
|
||||||
|
|
||||||
/// Reducer Function
|
|
||||||
fn reduce(self: Rc<Self>, action: Self::Action) -> Rc<Self> {
|
|
||||||
let next_ctr = match action {
|
|
||||||
CounterAction::Double => self.counter * 2,
|
|
||||||
CounterAction::Square => self.counter.pow(2)
|
|
||||||
};
|
|
||||||
|
|
||||||
Self { counter: next_ctr }.into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[function_component]
|
|
||||||
fn ReducerExample() -> Html {
|
|
||||||
// The use_reducer hook takes an initialization function which will be called only once.
|
|
||||||
let counter = use_reducer(CounterState::default);
|
|
||||||
|
|
||||||
let double_onclick = {
|
|
||||||
let counter = counter.clone();
|
|
||||||
Callback::from(move |_| counter.dispatch(CounterAction::Double))
|
|
||||||
};
|
|
||||||
let square_onclick = {
|
|
||||||
let counter = counter.clone();
|
|
||||||
Callback::from(move |_| counter.dispatch(CounterAction::Square))
|
|
||||||
};
|
|
||||||
|
|
||||||
html! {
|
|
||||||
<>
|
|
||||||
<div id="result">{ counter.counter }</div>
|
|
||||||
|
|
||||||
<button onclick={double_onclick}>{ "Double" }</button>
|
|
||||||
<button onclick={square_onclick}>{ "Square" }</button>
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
:::caution
|
|
||||||
|
|
||||||
The value held in the handle will reflect the value of at the time the
|
|
||||||
handle is returned by the `use_reducer`. It is possible that the handle does
|
|
||||||
not dereference to an up to date value if you are moving it into a
|
|
||||||
`use_effect_with_deps` hook. You can register the
|
|
||||||
state to the dependents so the hook can be updated when the value changes.
|
|
||||||
|
|
||||||
:::
|
|
||||||
|
|
||||||
## `use_reducer_eq`
|
|
||||||
|
|
||||||
This hook has the same effect as `use_reducer` but will only trigger a
|
|
||||||
re-render when the reducer function produces a value that `prev_state != next_state`.
|
|
||||||
|
|
||||||
This hook requires the state object to implement `PartialEq` in addition
|
|
||||||
to the `Reducible` trait required by `use_reducer`.
|
|
|
@ -1,67 +0,0 @@
|
||||||
---
|
|
||||||
title: 'use_state'
|
|
||||||
---
|
|
||||||
|
|
||||||
`use_state` is used to manage state in a function component.
|
|
||||||
It returns a `UseStateHandle` object which `Deref`s to the currently stored value
|
|
||||||
and provides a `set` method to update the value.
|
|
||||||
|
|
||||||
The hook takes a function as input which determines the initial value.
|
|
||||||
|
|
||||||
:::tip Advanced tip
|
|
||||||
|
|
||||||
The setter function is guaranteed to be the same across the entire
|
|
||||||
component lifecycle. You can safely omit the `UseStateHandle` from the
|
|
||||||
dependents of `use_effect_with_deps` if you only intend to set
|
|
||||||
values from within the hook.
|
|
||||||
|
|
||||||
:::
|
|
||||||
|
|
||||||
This hook will always trigger a re-render upon receiving a new state. See
|
|
||||||
[`use_state_eq`](#use_state_eq) if you want the component to only
|
|
||||||
re-render when the new state compares unequal to the existing one.
|
|
||||||
|
|
||||||
## Example
|
|
||||||
|
|
||||||
```rust
|
|
||||||
use std::ops::Deref;
|
|
||||||
use yew::{Callback, function_component, html, use_state, Html};
|
|
||||||
|
|
||||||
#[function_component]
|
|
||||||
fn StateExample() -> Html {
|
|
||||||
let name_handle = use_state(|| String::from("Bob"));
|
|
||||||
let name = name_handle.deref().clone();
|
|
||||||
let onclick = {
|
|
||||||
let name = name.clone();
|
|
||||||
Callback::from(move |_| name_handle.set(format!("{}y Jr.", name)))
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
html! {
|
|
||||||
<div>
|
|
||||||
<button {onclick}>{ "Update name" }</button>
|
|
||||||
<p>
|
|
||||||
<b>{ "My name is: " }</b>
|
|
||||||
{ name }
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
:::caution
|
|
||||||
|
|
||||||
The value held in the handle will reflect the value at the time the
|
|
||||||
handle is returned by the `use_state`. It is possible that the handle
|
|
||||||
does not dereference to an up to date value if you are moving it into a
|
|
||||||
`use_effect_with_deps` hook. You can register the
|
|
||||||
state to the dependents so the hook can be updated when the value changes.
|
|
||||||
|
|
||||||
:::
|
|
||||||
|
|
||||||
## `use_state_eq`
|
|
||||||
|
|
||||||
This hook has the same effect as `use_state` but will only trigger a
|
|
||||||
re-render when the setter receives a value that `prev_state != next_state`.
|
|
||||||
|
|
||||||
This hook requires the state object to implement `PartialEq`.
|
|
|
@ -15,6 +15,7 @@ Do not manually modify the DOM tree that is rendered by Yew. Treat the `NodeRef`
|
||||||
access, if you are unsure.
|
access, if you are unsure.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
## Example
|
## Further Reading
|
||||||
|
|
||||||
See [use_node_ref hook](./hooks/use-node-ref)
|
- [use_node_ref hook](https://yew-rs-api.web.app/next/yew/functional/fn.use_node_ref.html)
|
||||||
|
- [`node_refs` example](https://github.com/yewstack/yew/tree/master/examples/node_refs)
|
||||||
|
|
|
@ -6,13 +6,21 @@ title: 'State'
|
||||||
|
|
||||||
This table can be used as a guide when deciding what state storing type fits best for your use case:
|
This table can be used as a guide when deciding what state storing type fits best for your use case:
|
||||||
|
|
||||||
| Hook | Type | Rerender when? | Scope |
|
| Hook | Type | Rerender when? | Scope |
|
||||||
| ---------------------------------------------------- | -------------------------- | ---------------------------- | ------------------- |
|
| ------------------------ | -------------------------- | ---------------------------- | ------------------- |
|
||||||
| [use_state](./hooks/use-state) | `T` | got set | component instance |
|
| [use_state] | `T` | got set | component instance |
|
||||||
| [use_state_eq](./hooks/use-state#use_state_eq) | `T: PartialEq` | got set with diff. value | component instance |
|
| [use_state_eq] | `T: PartialEq` | got set with diff. value | component instance |
|
||||||
| [use_reducer](./hooks/use-reducer) | `T: Reducible` | got reduced | component instance |
|
| [use_reducer] | `T: Reducible` | got reduced | component instance |
|
||||||
| [use_reducer_eq](./hooks/use-reducer#use_reducer_eq) | `T: Reducible + PartialEq` | got reduced with diff. value | component instance |
|
| [use_reducer_eq] | `T: Reducible + PartialEq` | got reduced with diff. value | component instance |
|
||||||
| [use_memo](./hooks/use-memo) | `Deps -> T` | dependencies changed | component instance |
|
| [use_memo] | `Deps -> T` | dependencies changed | component instance |
|
||||||
| [use_callback](./hooks/use-callback) | `Deps -> Callback<E>` | dependencies changed | component instance |
|
| [use_callback] | `Deps -> Callback<E>` | dependencies changed | component instance |
|
||||||
| [use_mut_ref](./hooks/use-mut-ref) | `T` | - | component instance |
|
| [use_mut_ref] | `T` | - | component instance |
|
||||||
| a static global variable | `T` | - | global, used by all |
|
| a static global variable | `T` | - | global, used by all |
|
||||||
|
|
||||||
|
[use_state]: https://yew-rs-api.web.app/next/yew/functional/fn.use_state.html
|
||||||
|
[use_state_eq]: https://yew-rs-api.web.app/next/yew/functional/fn.use_state_eq.html
|
||||||
|
[use_reducer]: https://yew-rs-api.web.app/next/yew/functional/fn.use_reducer.html
|
||||||
|
[use_reducer_eq]: https://yew-rs-api.web.app/next/yew/functional/fn.use_reducer_eq.html
|
||||||
|
[use_memo]: https://yew-rs-api.web.app/next/yew/functional/fn.use_memo.html
|
||||||
|
[use_callback]: https://yew-rs-api.web.app/next/yew/functional/fn.use_callback.html
|
||||||
|
[use_mut_ref]: https://yew-rs-api.web.app/next/yew/functional/fn.use_mut_ref.html
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -67,15 +67,6 @@ module.exports = {
|
||||||
id: 'concepts/function-components/hooks/introduction',
|
id: 'concepts/function-components/hooks/introduction',
|
||||||
},
|
},
|
||||||
items: [
|
items: [
|
||||||
'concepts/function-components/hooks/use-state',
|
|
||||||
'concepts/function-components/hooks/use-reducer',
|
|
||||||
'concepts/function-components/hooks/use-mut-ref',
|
|
||||||
'concepts/function-components/hooks/use-node-ref',
|
|
||||||
'concepts/function-components/hooks/use-effect',
|
|
||||||
'concepts/function-components/hooks/use-memo',
|
|
||||||
'concepts/function-components/hooks/use-callback',
|
|
||||||
'concepts/function-components/hooks/use-context',
|
|
||||||
'concepts/function-components/hooks/use-force-update',
|
|
||||||
'concepts/function-components/hooks/custom-hooks',
|
'concepts/function-components/hooks/custom-hooks',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue