1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
//! # Performance
//!
//! Collection of things to avoid and improve to have a better performance.
//!
//! ### 1. Using use_effect to synchronize state
//! The `use_effect` hook is sometimes missused as a synchronization between states
//!
//! ```rust
//! # use freya::prelude::*;
//! fn app() -> Element {
//!     let mut state = use_signal(|| 1);
//!     let mut double_state = use_signal(|| 1);
//!
//!     use_effect(move || {
//!         // Update double_state whenever `state` changes
//!         double_state.set(state() * 2)
//!     });
//!
//!     rsx!(
//!         label {
//!             onclick: move |_| state += 1,
//!             "{state} * 2 = {double_state}"
//!         }
//!     )
//! }
//! ```
//!
//! This is bad because we are storing a derived value (double_state) in an unnecessary reactive wrapper (signal).
//! The flow would have been:
//! ```ignore
//!                              (initial) -> state: 0 , double_state: 0
//!                   (state gets updated) -> state: 1 , double_state: 0
//! (effect runs and updates double_state) -> state: 1 , double_state: 1
//! ```
//!
//!
//! #### Manual signal derivation
//!
//! We can simply create a temporary variable in which to store the derived value from the signal.
//! Because we are reading `double_state`, whenever `state` changes this component function will reerun, so `double_state` will always be up to date.
//!
//! ```rust
//! # use freya::prelude::*;
//! fn app() -> Element {
//!     let mut state = use_signal(|| 1);
//!     let double_state = state() * 2;
//!
//!     rsx!(
//!         label {
//!             onclick: move |_| state += 1,
//!             "{state} * 2 = {double_state}"
//!         }
//!     )
//! }
//! ```
//!
//! Now, the flow would be:
//! ```ignore
//!                                     (initial) -> state: 0 , double_state: 0
//! (state gets updated and double_state derived) -> state: 1 , double_state: 1
//! ```
//!
//! ### Reactive signal derivation
//!
//! We can also use `use_memo` to memoize derived values. This is very useful for values that are expensive to compute (which isn't the case with simple numeric operation)
//!
//! ```rust
//! # use freya::prelude::*;
//! fn app() -> Element {
//!     let mut state = use_signal(|| 1);
//!     let double_state = use_memo(move || state() * 2);
//!
//!     rsx!(
//!         label {
//!             onclick: move |_| state += 1,
//!             "{state} * 2 = {double_state}"
//!         }
//!     )
//! }
//! ```
//!
//! The flow would be:
//! ```ignore
//!                                                    (initial) -> state: 0 , double_state: 0
//! (state gets updated and double_state memo run synchronously) -> state: 1 , double_state: 1
//! ```