Skip to content

Commit

Permalink
showcase let syntax in For (#151)
Browse files Browse the repository at this point in the history
Co-authored-by: Oliver Nordh <[email protected]>
  • Loading branch information
purung and Oliver Nordh authored Jan 31, 2025
1 parent bf566af commit 27eb5e2
Showing 1 changed file with 16 additions and 7 deletions.
23 changes: 16 additions & 7 deletions src/view/04b_iteration.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,22 +60,32 @@ pub fn App() -> impl IntoView {
<For
each=move || data.get()
key=|state| state.key.clone()
let:child
let(child)
>
<p>{child.value}</p>
</For>
}
}
```

> Note the `let:child` syntax here. In the previous chapter we introduced `<For/>`
> Note the `let(child)` syntax here. In the previous chapter we introduced `<For/>`
> with a `children` prop. We can actually create this value directly in the children
> of the `<For/>` component, without breaking out of the `view` macro: the `let:child`
> combined with `<p>{child.value}</p>` above is the equivalent of
>
> ```rust
> children=|child| view! { <p>{child.value}</p> }
> ```
>
> For convenience, you can also choose to destructure the pattern of your data:
>
> ```rust
> <For
> each=move || data.get()
> key=|state| state.key.clone()
> let(DatabaseEntry { key, value })
> >
> ```
When you click the `Update Values` button... nothing happens. Or rather:
the signal is updated, the new value is logged, but the `{child.value}`
Expand Down Expand Up @@ -107,7 +117,7 @@ because the key didn’t change. So: why not just force the key to change?
<For
each=move || data.get()
key=|state| (state.key.clone(), state.value)
let:child
let(child)
>
<p>{child.value}</p>
</For>
Expand Down Expand Up @@ -184,7 +194,7 @@ pub fn App() -> impl IntoView {
<For
each=move || data.get()
key=|state| state.key.clone()
let:child
let(child)
>
<p>{child.value}</p>
</For>
Expand Down Expand Up @@ -319,7 +329,7 @@ Because `rows` is a keyed field, it implements `IntoIterator`, and we can simply

The `key` field calls `.read()` to get access to the current value of the row, then clones and returns the `key` field.

In `children` prop, calling `child.value()` gives us reactive access to the `value` field for the row with this key. If rows are reordered, added, or removed, the keyed store field will keep in sync so that this `value` is always associated with the correct key.
In `children` prop, calling `child.value()` gives us reactive access to the `value` field for the row with this key. If rows are reordered, added, or removed, the keyed store field will keep in sync so that this `value` is always associated with the correct key.

In the update button handler, we’ll iterate over the entries in `rows`, updating each one:
```rust
Expand All @@ -328,7 +338,7 @@ for row in data.rows().iter_unkeyed() {
}
```

### Pros
### Pros

We get the fine-grained reactivity of the nested-signal and memo versions, without needing to manually create nested signals or memoized slices. We can work with plain data (a struct and `Vec<_>`), annotated with a derive macro, rather than special nested reactive types.

Expand Down Expand Up @@ -371,7 +381,6 @@ pub fn App() -> impl IntoView {
use reactive_stores::StoreFieldIterator;
// calling rows() gives us access to the rows
// .iter_unkeyed
for row in data.rows().iter_unkeyed() {
*row.value().write() *= 2;
}
Expand Down

0 comments on commit 27eb5e2

Please sign in to comment.