Browse Source

fix outlets being updated out of order

Evan Almloff 2 năm trước cách đây
mục cha
commit
46017d5b7e

+ 4 - 2
packages/router-macro/src/lib.rs

@@ -297,11 +297,13 @@ impl RouteEnum {
                             #index_iter => {
                                 match myself {
                                     #layers
-                                    _ => panic!("Route::render called with invalid level {}", level),
+                                    // _ => panic!("Route::render called with invalid level {}", level),
+                                    _ => None
                                 }
                             },
                         )*
-                        _ => panic!("Route::render called with invalid level {}", level),
+                        // _ => panic!("Route::render called with invalid level {}", level),
+                        _ => None
                     }
                 }
             }

+ 28 - 7
packages/router/src/components/router.rs

@@ -3,18 +3,39 @@ use log::error;
 use std::{cell::RefCell, str::FromStr};
 
 use crate::{
-    prelude::{outlet::OutletContext, RouterContext},
+    prelude::{Outlet, RouterContext},
     routable::Routable,
     router_cfg::RouterConfiguration,
 };
 
+/// The config for [`Router`].
+pub struct RouterCfg<R: Routable> {
+    config: RefCell<Option<RouterConfiguration<R>>>,
+}
+
+impl<R: Routable> Default for RouterCfg<R> {
+    fn default() -> Self {
+        Self {
+            config: RefCell::new(Some(RouterConfiguration::default())),
+        }
+    }
+}
+
+impl<R: Routable> From<RouterConfiguration<R>> for RouterCfg<R> {
+    fn from(value: RouterConfiguration<R>) -> Self {
+        Self {
+            config: RefCell::new(Some(value)),
+        }
+    }
+}
+
 /// The props for [`Router`].
 #[derive(Props)]
 pub struct RouterProps<R: Routable> {
     #[props(into)]
     initial_url: Option<String>,
     #[props(default, into)]
-    config: RefCell<Option<RouterConfiguration<R>>>,
+    config: RouterCfg<R>,
 }
 
 impl<R: Routable> PartialEq for RouterProps<R> {
@@ -29,7 +50,7 @@ pub fn Router<R: Routable + Clone>(cx: Scope<RouterProps<R>>) -> Element
 where
     <R as FromStr>::Err: std::fmt::Display,
 {
-    let router = use_context_provider(cx, || {
+    use_context_provider(cx, || {
         #[allow(unreachable_code, unused_variables)]
         if let Some(outer) = cx.consume_context::<RouterContext<R>>() {
             let msg = "Router components should not be nested within each other";
@@ -38,7 +59,7 @@ where
             panic!("{}", msg);
         }
         let router = RouterContext::new(
-            cx.props.config.take().unwrap_or_default(),
+            cx.props.config.config.take().unwrap_or_default(),
             cx.schedule_update_any(),
         );
         if let Some(initial) = cx.props.initial_url.as_ref() {
@@ -51,7 +72,7 @@ where
         router
     });
 
-    use_context_provider(cx, || OutletContext { current_level: 1 });
-
-    router.current().render(cx, 0)
+    render! {
+        Outlet::<R> {}
+    }
 }

+ 4 - 1
packages/router/src/contexts/outlet.rs

@@ -8,7 +8,10 @@ pub(crate) struct OutletContext {
 }
 
 pub(crate) fn use_outlet_context(cx: &ScopeState) -> &OutletContext {
-    let outlet_context = use_context(cx).unwrap();
+    let outlet_context = cx.use_hook(|| {
+        cx.consume_context()
+            .unwrap_or(OutletContext { current_level: 0 })
+    });
     outlet_context
 }