diff_component.rs 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. use dioxus::core::{ElementId, Mutation::*};
  2. use dioxus::prelude::*;
  3. /// When returning sets of components, we do a light diff of the contents to preserve some react-like functionality
  4. ///
  5. /// This means that nav_bar should never get re-created and that we should only be swapping out
  6. /// different pointers
  7. #[test]
  8. fn component_swap() {
  9. fn app(cx: Scope) -> Element {
  10. let render_phase = cx.use_hook(|| 0);
  11. *render_phase += 1;
  12. cx.render(match *render_phase {
  13. 0 => rsx! {
  14. nav_bar {}
  15. dash_board {}
  16. },
  17. 1 => rsx! {
  18. nav_bar {}
  19. dash_results {}
  20. },
  21. 2 => rsx! {
  22. nav_bar {}
  23. dash_board {}
  24. },
  25. 3 => rsx! {
  26. nav_bar {}
  27. dash_results {}
  28. },
  29. 4 => rsx! {
  30. nav_bar {}
  31. dash_board {}
  32. },
  33. _ => rsx!("blah"),
  34. })
  35. }
  36. fn nav_bar(cx: Scope) -> Element {
  37. cx.render(rsx! {
  38. h1 {
  39. "NavBar"
  40. (0..3).map(|_| rsx!(nav_link {}))
  41. }
  42. })
  43. }
  44. fn nav_link(cx: Scope) -> Element {
  45. cx.render(rsx!( h1 { "nav_link" } ))
  46. }
  47. fn dash_board(cx: Scope) -> Element {
  48. cx.render(rsx!( div { "dashboard" } ))
  49. }
  50. fn dash_results(cx: Scope) -> Element {
  51. cx.render(rsx!( div { "results" } ))
  52. }
  53. let mut dom = VirtualDom::new(app);
  54. {
  55. let edits = dom.rebuild().santize();
  56. assert_eq!(
  57. edits.edits,
  58. [
  59. LoadTemplate { name: "template", index: 0, id: ElementId(1) },
  60. LoadTemplate { name: "template", index: 0, id: ElementId(2) },
  61. LoadTemplate { name: "template", index: 0, id: ElementId(3) },
  62. LoadTemplate { name: "template", index: 0, id: ElementId(4) },
  63. ReplacePlaceholder { path: &[1], m: 3 },
  64. LoadTemplate { name: "template", index: 0, id: ElementId(5) },
  65. AppendChildren { m: 2, id: ElementId(0) }
  66. ]
  67. );
  68. }
  69. dom.mark_dirty(ScopeId(0));
  70. assert_eq!(
  71. dom.render_immediate().santize().edits,
  72. [
  73. LoadTemplate { name: "template", index: 0, id: ElementId(6) },
  74. ReplaceWith { id: ElementId(5), m: 1 }
  75. ]
  76. );
  77. dom.mark_dirty(ScopeId(0));
  78. assert_eq!(
  79. dom.render_immediate().santize().edits,
  80. [
  81. LoadTemplate { name: "template", index: 0, id: ElementId(5) },
  82. ReplaceWith { id: ElementId(6), m: 1 }
  83. ]
  84. );
  85. dom.mark_dirty(ScopeId(0));
  86. assert_eq!(
  87. dom.render_immediate().santize().edits,
  88. [
  89. LoadTemplate { name: "template", index: 0, id: ElementId(6) },
  90. ReplaceWith { id: ElementId(5), m: 1 }
  91. ]
  92. );
  93. }