You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs-src/0.7/src/essentials/basics/collections.md
+63-16Lines changed: 63 additions & 16 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -20,9 +20,9 @@ To make working with structs and collections easier, Dioxus provides the **Store
20
20
21
21
## Reactive Stores
22
22
23
-
In Dioxus, reactive stores are types that isolate reactivity to just a single field or entry in a collection. Stores allow us to "zoom in" on a smaller portion of our data, ignoring all other reads and writes.
23
+
In Dioxus, reactive stores are types that isolate reactivity to just a path in a data structure. Stores allow us to "zoom in" on a smaller portion of our data, ignoring all other reads and writes.
24
24
25
-
The simplest stores are structs that derive the`Store` trait:
25
+
The simplest stores are structs that derive a`Store` trait:
26
26
27
27
```rust
28
28
#[derive(Store)]
@@ -41,7 +41,7 @@ let header = use_store(|| HeaderState {
41
41
});
42
42
```
43
43
44
-
The `Store` drive macro generates additional methods on `HeaderState` that allow us to "zoom in" to fields of the struct. We access the fields by calling the field name like a method:
44
+
The `Store` drive macro generates additional methods on `Store<HeaderState>` that allow us to "zoom in" to fields of the struct. We access the fields by calling the field name like a method:
45
45
46
46
```rust
47
47
fnapp() ->Element {
@@ -74,13 +74,22 @@ Notice how the default `Store` we get from `use_store` has an elided default gen
Because the lens is "unnamable," we can't easily add it to structs or pass it as a function argument. In these cases, we can use the `boxed` and `boxed_mut` methods to convert the lens into a ReadSignal or WriteSignal at the cost of an allocation:
77
+
Because the lens is "unnamable", we need to accept the lens as a generic in any functions that work with stores. If we only need to read the store, we can require the lens implements the `Readable` trait. If we need to write to the store, we can require the lens implements the `Writable` trait.
On the boundary of components, this is done automatically by "decaying" lenses into ReadSignals:
91
+
On the component boundary, Stores are automatically boxed and converted to `ReadSignal` or `ReadStore` as needed so you don't need to worry about the lens type:
92
+
84
93
85
94
```rust
86
95
fnapp() ->Element {
@@ -92,13 +101,20 @@ fn app() -> Element {
92
101
rsx! {
93
102
// the lens returned by `.title()` decays into a `ReadSignal` automatically!
94
103
Title { title:header.title() }
104
+
// the lens returned by `.subtitle()` decays into a `ReadStore` automatically!
@@ -213,7 +229,7 @@ let len = match header.subtitle().transpose() {
213
229
};
214
230
```
215
231
216
-
Alternatively, we can use `.ref()` the lens to gain access to the underlying value, but we lose the ability to reactively "zoom in" further:
232
+
Alternatively, we can use `.as_ref()` the lens to gain access to the underlying value, but we lose the ability to reactively "zoom in" further:
217
233
218
234
```rust
219
235
letlen=matchheader.subtitle().as_ref() {
@@ -222,7 +238,7 @@ let len = match header.subtitle().as_ref() {
222
238
};
223
239
```
224
240
225
-
You can usually choose either approach - just know that using `.ref()` calls `.read()` internally, and the "reactivity zoom" might not be perfectly precise.
241
+
You can usually choose either approach - just know that using `.as_ref()` calls `.read()` internally, and the "reactivity zoom" might not be perfectly precise.
@@ -301,24 +317,55 @@ fn ListItem(user: ReadSignal<UserData>) -> Element {
301
317
302
318
The `Store<HashMap<K, V>>` type is a special type that implements reactivity on a per-entry basis. When we insert or remove values from the `users` store, only *one* re-render is queued. If we edit an individual entry in the HashMap, only a single `ListItem` will re-render.
303
319
304
-
Alternatively, we could pass the entire `Store`to the ListItem, along with the `UserId` key, allowing us to further lens into specific fields of our UserData entries:
320
+
Alternatively, we could derive `Store`on our `UserData` type, and accept `ReadStore<UserData>`allowing us to further lens into specific fields of our UserData entry:
You can extend your store types with methods with the `#[store]` attribute macro. Methods inside the macro are converted into an extension trait that is automatically implemented for `Store<T, Lens>`. The macro will automatically add bounds to the `Lens` generic based on the self parameter of the method. If the method takes `&self`, the `Lens` will be bound by `Readable`. If the method takes `&mut self`, the `Lens` will be bound by `Writable`.
0 commit comments