fix: use_route should subscribe to changes to the route

This commit is contained in:
Jonathan Kelley committed 2022-01-28 12:00:13 -05:00
1 parent ccbb955b7b
commit a21e7d4dd1
2 files changed
+38 -8

No files matched your search

+25 -7
View File
@@ -1,4 +1,4 @@
use dioxus_core::ScopeState; use dioxus_core::{ScopeId, ScopeState};
use gloo::history::{HistoryResult, Location}; use gloo::history::{HistoryResult, Location};
use serde::de::DeserializeOwned; use serde::de::DeserializeOwned;
use std::{rc::Rc, str::FromStr}; use std::{rc::Rc, str::FromStr};
@@ -74,10 +74,28 @@ impl UseRoute {
/// This hook provides access to information about the current location in the /// This hook provides access to information about the current location in the
/// context of a [`Router`]. If this function is called outside of a `Router` /// context of a [`Router`]. If this function is called outside of a `Router`
/// component it will panic. /// component it will panic.
pub fn use_route(cx: &ScopeState) -> UseRoute { pub fn use_route(cx: &ScopeState) -> &UseRoute {
let router = cx &cx.use_hook(|_| {
.consume_context::<RouterService>() let router = cx
.expect("Cannot call use_route outside the scope of a Router component") .consume_context::<RouterService>()
.clone(); .expect("Cannot call use_route outside the scope of a Router component");
UseRoute { router }
router.subscribe_onchange(cx.scope_id());
UseRouteInner {
router: UseRoute { router },
scope: cx.scope_id(),
}
})
.router
}
struct UseRouteInner {
router: UseRoute,
scope: ScopeId,
}
impl Drop for UseRouteInner {
fn drop(&mut self) {
self.router.router.unsubscribe_onchange(self.scope)
}
} }
+13 -1
View File
@@ -1,7 +1,7 @@
use gloo::history::{BrowserHistory, History, HistoryListener, Location}; use gloo::history::{BrowserHistory, History, HistoryListener, Location};
use std::{ use std::{
cell::{Cell, Ref, RefCell}, cell::{Cell, Ref, RefCell},
collections::HashMap, collections::{HashMap, HashSet},
rc::Rc, rc::Rc,
}; };
@@ -12,6 +12,7 @@ pub struct RouterService {
pub(crate) pending_events: Rc<RefCell<Vec<RouteEvent>>>, pub(crate) pending_events: Rc<RefCell<Vec<RouteEvent>>>,
history: Rc<RefCell<BrowserHistory>>, history: Rc<RefCell<BrowserHistory>>,
slots: Rc<RefCell<Vec<(ScopeId, String)>>>, slots: Rc<RefCell<Vec<(ScopeId, String)>>>,
onchange_listeners: Rc<RefCell<HashSet<ScopeId>>>,
root_found: Rc<Cell<Option<ScopeId>>>, root_found: Rc<Cell<Option<ScopeId>>>,
cur_path_params: Rc<RefCell<HashMap<String, String>>>, cur_path_params: Rc<RefCell<HashMap<String, String>>>,
listener: HistoryListener, listener: HistoryListener,
@@ -73,6 +74,7 @@ impl RouterService {
regen_route, regen_route,
slots, slots,
pending_events, pending_events,
onchange_listeners: Rc::new(RefCell::new(HashSet::new())),
cur_path_params: Rc::new(RefCell::new(HashMap::new())), cur_path_params: Rc::new(RefCell::new(HashMap::new())),
} }
} }
@@ -143,6 +145,16 @@ impl RouterService {
pub fn current_path_params(&self) -> Ref<HashMap<String, String>> { pub fn current_path_params(&self) -> Ref<HashMap<String, String>> {
self.cur_path_params.borrow() self.cur_path_params.borrow()
} }
pub fn subscribe_onchange(&self, id: ScopeId) {
log::trace!("Subscribing onchange for scope id {:?}", id);
self.onchange_listeners.borrow_mut().insert(id);
}
pub fn unsubscribe_onchange(&self, id: ScopeId) {
log::trace!("Subscribing onchange for scope id {:?}", id);
self.onchange_listeners.borrow_mut().remove(&id);
}
} }
fn clean_route(route: String) -> String { fn clean_route(route: String) -> String {