Lists
Iterators
Yew supports two different syntaxes for building HTML from an iterator.
- Syntax type 1
- Syntax type 2
The first is to call collect::<Html>()
on the final transform in your iterator, which returns a
list that Yew can display.
use yew::prelude::*;
let items = (1..=10).collect::<Vec<_>>();
html! {
<ul class="item-list">
{ items.iter().collect::<Html>() }
</ul>
};
The alternative is to use the for
keyword, which is not native Rust syntax and instead is used by
the HTML macro to output the needed code to display the iterator.
use yew::prelude::*;
let items = (1..=10).collect::<Vec<_>>();
html! {
<ul class="item-list">
{ for items.iter() }
</ul>
};
Keyed lists
A keyed list is an optimized list that has keys on all children.
key
is a special prop provided by Yew that gives an HTML element or component a unique identifier
that is used for optimization purposes inside Yew.
Key has to be unique only in each list, in contrast to the global uniqueness of HTML id
s. It must not depend on the order of the list.
It is always recommended to add keys to lists.
Keys can be added by passing a unique String
, str
or integer to the special key
prop:
use yew::prelude::*;
let names = vec!["Sam","Bob","Ray"]
html! {
<div id="introductions">
{
names.into_iter().map(|name| {
html!{<div key={name}>{ format!("Hello, I'am {}!",name) }</div>}
}).collect::<Html>()
}
</div>
};
Performance increases
We have Keyed list example that lets you test the performance improvements, but here is a rough rundown:
- Go to Keyed list hosted demo
- Add 500 elements.
- Disable keys.
- Reverse the list.
- Look at "The last rendering took Xms" (At the time of writing this it was ~60ms)
- Enable keys.
- Reverse the list.
- Look at "The last rendering took Xms" (At the time of writing this it was ~30ms)
So just at the time of writing this, for 500 components it is a 2x increase of speed.
Detailed explanation
Usually, you just need a key on every list item when you iterate and the order of data can change. It's used to speed up the reconciliation process when re-rendering the list.
Without keys, assume you iterate through ["bob", "sam", "rob"]
, ending up with the HTML:
<div id="bob">My name is Bob</div>
<div id="sam">My name is Sam</div>
<div id="rob">My name is rob</div>
Then on the next render, if your list changed to ["bob", "rob"]
, yew could delete
the element with id="rob" and update id="sam" to be id="rob"
If you had added a key to each element, the initial HTML would be the same, but after
the render with the modified list, ["bob", "rob"]
, yew would just delete the second
HTML element and leave the rest untouched since it can use the keys to associate them.
If you ever encounter a bug/"feature" where you switch from one component to another but both have a div as the highest rendered element. Yew reuses the rendered HTML div in those cases as an optimization. If you need that div to be recreated instead of reused, then you can add different keys and they will not be reused.