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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
//! # Hooks
//!
//! Hooks are special functions to be used inside of Components that lets you handle different things like the state or lifecycle of your component. They are usually prefixed with `use`, e.g `use_signal`, `use_effect`, `use_memo`, etc.
//!
//! # Rules of Hooks
//!
//! Even though hooks appear to be normal functions they are in fact special so you cannot just call them however you want.
//!
//! ## 1. They cannot be called conditionally
//!
//! You cannot do the following because hooks need to maintain their order. So, if one component is calling 3 different hooks in one render, and then in another render if just calls 2, it would be breaking this rule.
//!
//! ❌:
//! ```rust
//! # use freya::prelude::*;
//! #[component]
//! fn MyComponent(value: bool) -> Element {
//!     let is_enabled = if value {
//!         // This should be moved out of the conditional
//!         let state = use_signal(|| value);
//!
//!         state()
//!     } else {
//!         true
//!     };
//!
//!     None
//! }
//! ```
//!
//! ✅:
//! ```rust
//! # use freya::prelude::*;
//! #[component]
//! fn MyComponent(initial_value: bool) -> Element {
//!     let is_enabled = use_signal(move || initial_value);
//!
//!     None
//! }
//! ```
//!
//! ## 2. They can only be called inside of Component functions
//!
//! You cannot call them inside of event handlers, futures, etc.
//!
//! ❌:
//! ```rust
//! # use freya::prelude::*;
//! #[component]
//! fn MyComponent() -> Element {
//!     let onclick = |_| {
//!          let state = use_signal(|| false);
//!     };
//!
//!     rsx!(
//!         label {
//!             onclick,
//!             "Hello, World!"
//!         }
//!     )
//! }
//! ```
//!
//! ✅:
//! ```rust
//! # use freya::prelude::*;
//! #[component]
//! fn MyComponent() -> Element {
//!     let mut state = use_signal(|| false);
//!
//!     let onclick = move |_| {
//!          state.set(true);
//!     };
//!
//!     rsx!(
//!         label {
//!             onclick,
//!             "Hello, World!"
//!         }
//!     )
//! }
//! ```
//!
//! ## 3. They cannot be called in loops
//!
//! Hooks cannot be called in loops as the numbers of iterations might change between renders.
//!
//! ❌:
//! ```rust
//! # use freya::prelude::*;
//! #[component]
//! fn MyComponent() -> Element {
//!     for i in 0..5 {
//!         let state = use_signal(|| i);
//!     }
//!
//!     None
//! }
//! ```
//!
//! ✅:
//! ```rust
//! # use freya::prelude::*;
//! #[component]
//! fn MyComponent() -> Element {
//!     let state = use_signal(|| (0..5).into_iter().collect::<Vec<_>>());
//!
//!     None
//! }
//! ```