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
//! }
//! ```