docs: add rules of hooks

This commit is contained in:
Jonathan Kelley committed 2022-01-28 03:04:21 -05:00
1 parent 4fb2221ee1
commit 564284f4be
5 files changed
+113 -9

No files matched your search

+73
View File
@@ -76,6 +76,78 @@ This is why hooks called out of order will fail - if we try to downcast a `Hook<
This pattern might seem strange at first, but it can be a significant upgrade over structs as blobs of state, which tend to be difficult to use in [Rust given the ownership system](https://rust-lang.github.io/rfcs/2229-capture-disjoint-fields.html).
## Rules of hooks
Hooks are sensitive to how they are used. To use hooks, you must abide by the
"rules of hooks" (borrowed from react)](https://reactjs.org/docs/hooks-rules.html):
- Functions with "use_" should not be called in callbacks
- Functions with "use_" should not be called out of order
- Functions with "use_" should not be called in loops or conditionals
Examples of "no-nos" include:
### ❌ Nested uses
```rust
// ❌ don't call use_hook or any `use_` function *inside* use_hook!
cx.use_hook(|_| {
let name = cx.use_hook(|_| "ads");
})
// ✅ instead, move the first hook above
let name = cx.use_hook(|_| "ads");
cx.use_hook(|_| {
// do something with name here
})
```
### ❌ Uses in conditionals
```rust
// ❌ don't call use_ in conditionals!
if do_thing {
let name = use_state(&cx, || 0);
}
// ✅ instead, *always* call use_state but leave your logic
let name = use_state(&cx, || 0);
if do_thing {
// do thing with name here
}
```
### ❌ Uses in loops
```rust
// ❌ Do not use hooks in loops!
let mut nodes = vec![];
for name in names {
let age = use_state(&cx, |_| 0);
nodes.push(cx.render(rsx!{
div { "{age}" }
}))
}
// ✅ Instead, consider refactoring your usecase into components
#[inline_props]
fn Child(cx: Scope, name: String) -> Element {
let age = use_state(&cx, |_| 0);
cx.render(rsx!{ div { "{age}" } })
}
// ✅ Or, use a hashmap with use_ref
```rust
let ages = use_ref(&cx, |_| HashMap::new());
names.iter().map(|name| {
let age = ages.get(name).unwrap();
cx.render(rsx!{ div { "{age}" } })
})
```
## Building new Hooks
However, most hooks you'll interact with *don't* return an `&mut T` since this is not very useful in a real-world situation.
@@ -168,6 +240,7 @@ fn example(cx: Scope) -> Element {
```
## Hooks provided by the `Dioxus-Hooks` package
By default, we bundle a handful of hooks in the Dioxus-Hooks package. Feel free to click on each hook to view its definition and associated documentation.