navigation.rs 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. use dioxus::prelude::*;
  2. use dioxus_core::NoOpMutations;
  3. use std::sync::atomic::AtomicUsize;
  4. // Regression test for <https://github.com/DioxusLabs/dioxus/issues/3235>
  5. #[test]
  6. fn layout_retains_state_after_navigation() {
  7. let mut vdom = VirtualDom::new(app);
  8. vdom.rebuild_in_place();
  9. vdom.render_immediate(&mut NoOpMutations);
  10. let as_string = dioxus_ssr::render(&vdom);
  11. assert_eq!(as_string, "Other");
  12. }
  13. fn app() -> Element {
  14. rsx! {
  15. Router::<Route> {}
  16. }
  17. }
  18. // Turn off rustfmt since we're doing layouts and routes in the same enum
  19. #[derive(Routable, Clone, Debug, PartialEq)]
  20. #[rustfmt::skip]
  21. enum Route {
  22. // Wrap Home in a Navbar Layout
  23. #[layout(NavBar)]
  24. // The default route is always "/" unless otherwise specified
  25. #[route("/")]
  26. Home {},
  27. #[route("/other")]
  28. Other {},
  29. }
  30. #[component]
  31. fn NavBar() -> Element {
  32. static NAVBARS_CREATED: AtomicUsize = AtomicUsize::new(0);
  33. use_hook(|| {
  34. let navbars_created = NAVBARS_CREATED.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
  35. println!("creating navbar #{navbars_created}");
  36. if navbars_created > 0 {
  37. panic!("layouts should not be recreated when switching between two routes under the nav bar");
  38. }
  39. });
  40. // Queue an effect to navigate to the other route after rebuild_in_place
  41. use_effect(|| {
  42. router().push(Route::Other {});
  43. });
  44. rsx! {
  45. Outlet::<Route> {}
  46. }
  47. }
  48. #[component]
  49. fn Home() -> Element {
  50. rsx! {
  51. "Home!"
  52. }
  53. }
  54. #[component]
  55. fn Other() -> Element {
  56. rsx! {
  57. "Other"
  58. }
  59. }