From 81c094ed29fcdc5c6099492dd6ab09a59b79252c Mon Sep 17 00:00:00 2001 From: Dave Rolsky Date: Fri, 14 Jan 2022 14:55:12 -0600 Subject: [PATCH] Fix handling of re-renders in the Router Previously the router just stored a `root_found` boolean after it picked a route. But on re-render it would just always return false from `should_render` if this was true. This just aborted routing after a future resolved (or anything else that triggered a re-render). Now we store the matching ScopeId and check that against our routes in a re-render so we actually do re-render the matching route. --- packages/router/src/service.rs | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/packages/router/src/service.rs b/packages/router/src/service.rs index 2fac8509b..00642414f 100644 --- a/packages/router/src/service.rs +++ b/packages/router/src/service.rs @@ -11,7 +11,7 @@ pub struct RouterService { pub(crate) regen_route: Rc, history: Rc>, slots: Rc>>, - root_found: Rc>, + root_found: Rc>>, cur_path_params: Rc>>, listener: HistoryListener, } @@ -39,11 +39,11 @@ impl RouterService { let _slots = slots.clone(); - let root_found = Rc::new(Cell::new(false)); + let root_found = Rc::new(Cell::new(None)); let regen = regen_route.clone(); let _root_found = root_found.clone(); let listener = history.listen(move || { - _root_found.set(false); + _root_found.set(None); // checking if the route is valid is cheap, so we do it for (slot, root) in _slots.borrow_mut().iter().rev() { log::trace!("regenerating slot {:?} for root '{}'", slot, root); @@ -74,8 +74,13 @@ impl RouterService { pub fn should_render(&self, scope: ScopeId) -> bool { log::trace!("Should render scope id {:?}?", scope); - if self.root_found.get() { - log::trace!(" no - because root_found is true"); + if let Some(root_id) = self.root_found.get() { + log::trace!(" we already found a root with scope id {:?}", root_id); + if root_id == scope { + log::trace!(" yes - it's a match"); + return true; + } + log::trace!(" no - it's not a match"); return false; } @@ -89,7 +94,7 @@ impl RouterService { // fallback logic match root { - Some((_id, route)) => { + Some((id, route)) => { log::trace!( " matched given scope id {:?} with route root '{}'", scope, @@ -97,13 +102,13 @@ impl RouterService { ); if let Some(params) = route_matches_path(route, path) { log::trace!(" and it matches the current path '{}'", path); - self.root_found.set(true); + self.root_found.set(Some(*id)); *self.cur_path_params.borrow_mut() = params; true } else { if route == "" { log::trace!(" and the route is the root, so we will use that without a better match"); - self.root_found.set(true); + self.root_found.set(Some(*id)); true } else { log::trace!(" and the route '{}' is not the root nor does it match the current path", route);