1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
use dioxus::core::Mutation::*;
use dioxus::prelude::*;
use dioxus_core::ElementId;
// A real-world usecase of templates at peak performance
// In react, this would be a lot of node creation.
//
// In Dioxus, we memoize the rsx! body and simplify it down to a few template loads
//
// Also note that the IDs increase linearly. This lets us drive a vec on the renderer for O(1) re-indexing
fn app(cx: Scope) -> Element {
cx.render(rsx! {
div {
(0..3).map(|i| rsx! {
div {
h1 { "hello world! "}
p { "{i}" }
}
})
}
})
}
#[test]
fn list_renders() {
let mut dom = VirtualDom::new(app);
let edits = dom.rebuild().santize();
// note: we dont test template edits anymore
// assert_eq!(
// edits.templates,
// [
// // Create the outer div
// CreateElement { name: "div" },
// // todo: since this is the only child, we should just use
// // append when modify the values (IE no need for a placeholder)
// CreateStaticPlaceholder,
// AppendChildren { m: 1 },
// SaveTemplate { name: "template", m: 1 },
// // Create the inner template div
// CreateElement { name: "div" },
// CreateElement { name: "h1" },
// CreateStaticText { value: "hello world! " },
// AppendChildren { m: 1 },
// CreateElement { name: "p" },
// CreateTextPlaceholder,
// AppendChildren { m: 1 },
// AppendChildren { m: 2 },
// SaveTemplate { name: "template", m: 1 }
// ],
// );
assert_eq!(
edits.edits,
[
// Load the outer div
LoadTemplate { name: "template", index: 0, id: ElementId(1) },
// Load each template one-by-one, rehydrating it
LoadTemplate { name: "template", index: 0, id: ElementId(2) },
HydrateText { path: &[1, 0], value: "0", id: ElementId(3) },
LoadTemplate { name: "template", index: 0, id: ElementId(4) },
HydrateText { path: &[1, 0], value: "1", id: ElementId(5) },
LoadTemplate { name: "template", index: 0, id: ElementId(6) },
HydrateText { path: &[1, 0], value: "2", id: ElementId(7) },
// Replace the 0th childn on the div with the 3 templates on the stack
ReplacePlaceholder { m: 3, path: &[0] },
// Append the container div to the dom
AppendChildren { m: 1, id: ElementId(0) }
],
)
}