This is unreleased documentation for Yew Next version.
For up-to-date documentation, see the latest version on docs.rs.

yew/functional/hooks/
use_callback.rs

1use std::rc::Rc;
2
3use crate::callback::Callback;
4use crate::functional::{hook, use_memo};
5
6/// Get a immutable reference to a memoized `Callback`. Its state persists across renders.
7/// It will be recreated only if any of the dependencies changes value.
8///
9/// Memoization means it will only get recreated when provided dependencies update/change.
10/// This is useful when passing callbacks to optimized child components that rely on
11/// PartialEq to prevent unnecessary renders.
12///
13/// # Example
14///
15/// ```rust
16/// # use yew::prelude::*;
17/// #
18/// #[derive(Properties, PartialEq)]
19/// pub struct Props {
20///     pub callback: Callback<String, String>,
21/// }
22///
23/// #[function_component(MyComponent)]
24/// fn my_component(props: &Props) -> Html {
25///     let greeting = props.callback.emit("Yew".to_string());
26///
27///     html! {
28///         <>{ &greeting }</>
29///     }
30/// }
31///
32/// #[function_component(UseCallback)]
33/// fn callback() -> Html {
34///     let counter = use_state(|| 0);
35///     let onclick = {
36///         let counter = counter.clone();
37///         Callback::from(move |_| counter.set(*counter + 1))
38///     };
39///
40///     // This callback depends on (), so it's created only once, then MyComponent
41///     // will be rendered only once even when you click the button multiple times.
42///     let callback = use_callback((), move |name, _| format!("Hello, {}!", name));
43///
44///     // It can also be used for events, this callback depends on `counter`.
45///     let oncallback = use_callback(counter.clone(), move |_e, counter| {
46///         let _ = **counter;
47///     });
48///
49///     html! {
50///         <div>
51///             <button {onclick}>{ "Increment value" }</button>
52///             <button onclick={oncallback}>{ "Callback" }</button>
53///             <p>
54///                 <b>{ "Current value: " }</b>
55///                 { *counter }
56///             </p>
57///             <MyComponent {callback} />
58///         </div>
59///     }
60/// }
61/// ```
62#[hook]
63pub fn use_callback<IN, OUT, F, D>(deps: D, f: F) -> Callback<IN, OUT>
64where
65    IN: 'static,
66    OUT: 'static,
67    F: Fn(IN, &D) -> OUT + 'static,
68    D: PartialEq + 'static,
69{
70    let deps = Rc::new(deps);
71
72    (*use_memo(deps, move |deps| {
73        let deps = deps.clone();
74        let f = move |value: IN| f(value, deps.as_ref());
75        Callback::from(f)
76    }))
77    .clone()
78}