-
Hi, I've been struggling to understand an issue with constructing a Consider this example use std::collections::HashSet;
use leptos::html;
use leptos::prelude::*;
#[component]
pub fn NodeList() -> impl IntoView {
let mut nodes = HashSet::new();
nodes.insert((1, 1));
nodes.insert((2, 2));
nodes.insert((3, 3));
let li_items = nodes
.into_iter()
.map(|coord| {
let text = format!("{:?}", coord);
println!("rendering li: {} {} -> {}", coord.0, coord.1, text);
html::custom("li")
.attr("x", coord.0)
.attr("y", coord.1)
.child(text)
})
.collect_view();
view! {
<ul>
{li_items}
</ul>
}
} It may result in a final HTML like this: <ul>
<li x="2" y="2">(1, 1)</li>
<li x="1" y="1">(3, 3)</li>
<li x="3" y="3">(2, 2)</li>
</ul>
.map(|coord| {
let text = format!("{:?}", coord);
println!("rendering li: {} {} -> {}", coord.0, coord.1, text);
html::custom("li")
.attr("x", coord.0)
.attr("y", coord.1)
.child(text)
})
let text = format!("{:?}", coord);
println!("rendering li: {} {} -> {}", coord.0, coord.1, text);
How should I reason about this? 🤔 Anything interesting happening during the hydration? I've tested this on leptos |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 1 reply
-
Depending on the particular implementation, attributes and text nodes may be set to the current (browser) version during hydration, or they may assume that the rendered (server) version is correct and move on. Even if the behavior was consistent here it would be very confusing when you made a change on the client because the client state would be inconsistent with what had been rendered on the server. (I just ran into a bug like this in my own work last week!) If you want a data structure with a stable iteration order, you can use |
Beta Was this translation helpful? Give feedback.
-
That makes sense. I'm also trying to build a better understanding of leptos runtime: personally I would have expected that all of this code is server rendered. Why would the framework decide that it needs to re-render this component on the Web browser? 🤔 |
Beta Was this translation helpful? Give feedback.
HashSet
, likeHashMap
, has a randomized/arbitrary iteration order (see docs) Pretty much any time you have a hydration issue withHashMap
/HashSet
, this is why: the items are being iterated over in a different order on the server from the order in the client.Depending on the particular implementation, attributes and text nodes may be set to the current (browser) version during hydration, or they may assume that the rendered (server) version is correct and move on. Even if the behavior was consistent here it would be very confusing when you made a change on the client because the client state would be inconsistent with what had been rendered on the server. (I just ran into a bug like this …