yew_hooks/hooks/
use_logger.rs

1use std::fmt::Debug;
2use std::rc::Rc;
3
4use yew::prelude::*;
5
6use super::{use_effect_once, use_effect_update, use_effect_update_with_deps, use_previous};
7
8/// This hook logs in console as component goes through life-cycles.
9///
10/// # Example
11///
12/// ```rust
13/// # use yew::prelude::*;
14/// #
15/// use yew_hooks::prelude::*;
16///
17/// #[function_component(UseLogger)]
18/// fn logger(props: &Props) -> Html {
19///     use_logger("MyComponent".to_string(), props.clone());
20///
21///     let c = use_state(|| 0);
22///     let d = use_state(|| "d".to_string());
23///     use_logger("MyComponent".to_string(), (c.clone(), d.clone()));
24///     
25///     html! {
26///         <>
27///             <b>{ " a: " }</b> { props.a }
28///             <b>{ " b: " }</b> { &props.b }
29///             <b>{ " c: " }</b> { *c }
30///             <b>{ " d: " }</b> { &*d }
31///         </>
32///     }
33/// }
34///
35/// #[derive(Debug, Properties, PartialEq, Clone)]
36/// struct Props {
37///     pub a: i32,
38///     pub b: String,
39/// }
40/// ```
41#[hook]
42pub fn use_logger<T>(name: String, props: T)
43where
44    T: Debug + 'static,
45{
46    let name = Rc::new(name);
47    let props = Rc::new(props);
48
49    {
50        let name = name.clone();
51        let props = props.clone();
52
53        use_effect_once(move || {
54            log::debug!("{name} mounted: {props:?}");
55
56            move || log::debug!("{name} unmounted")
57        });
58    }
59
60    use_effect_update(move || {
61        log::debug!("{name} updated: {props:?}");
62        || ()
63    });
64}
65
66/// This hook logs in console as component goes through life-cycles.
67/// Like [`use_logger`] but only logs when `prev_state != next_state`.
68/// This requires the props to implement [`PartialEq`].
69///
70/// # Example
71///
72/// ```rust
73/// # use yew::prelude::*;
74/// #
75/// use yew_hooks::prelude::*;
76///
77/// #[function_component(UseLogger)]
78/// fn logger(props: &Props) -> Html {
79///     use_logger_eq("MyComponent".to_string(), props.clone());
80///
81///     let c = use_state(|| 0);
82///     let d = use_state(|| "d".to_string());
83///     use_logger_eq("MyComponent".to_string(), (c.clone(), d.clone()));
84///     
85///     html! {
86///         <>
87///             <b>{ " a: " }</b> { props.a }
88///             <b>{ " b: " }</b> { &props.b }
89///             <b>{ " c: " }</b> { *c }
90///             <b>{ " d: " }</b> { &*d }
91///         </>
92///     }
93/// }
94///
95/// #[derive(Debug, Properties, PartialEq, Clone)]
96/// struct Props {
97///     pub a: i32,
98///     pub b: String,
99/// }
100/// ```
101#[hook]
102pub fn use_logger_eq<T>(name: String, props: T)
103where
104    T: Debug + PartialEq + 'static,
105{
106    let name = Rc::new(name);
107    let props = Rc::new(props);
108    let props_prev = use_previous(props.clone());
109
110    {
111        let name = name.clone();
112        let props = props.clone();
113
114        use_effect_once(move || {
115            log::debug!("{name} mounted: {props:?}");
116
117            move || log::debug!("{name} unmounted")
118        });
119    }
120
121    use_effect_update_with_deps(
122        move |props| {
123            log::debug!("{} updated: from {:?}, to {:?}", name, *props_prev, props);
124            || ()
125        },
126        props,
127    );
128}