Explorar o código

Make deprecated use router (#1260)

* make router props expansion better

* fix router data fields

* make a deprecated use_router hook
ealmloff hai 1 ano
pai
achega
cfd62e274e

+ 0 - 4
examples/router.rs

@@ -43,7 +43,6 @@ fn App(cx: Scope) -> Element {
     }
 }
 
-#[inline_props]
 fn NavBar(cx: Scope) -> Element {
     render! {
         nav {
@@ -56,14 +55,12 @@ fn NavBar(cx: Scope) -> Element {
     }
 }
 
-#[inline_props]
 fn Home(cx: Scope) -> Element {
     render! {
         h1 { "Welcome to the Dioxus Blog!" }
     }
 }
 
-#[inline_props]
 fn Blog(cx: Scope) -> Element {
     render! {
         h1 { "Blog" }
@@ -71,7 +68,6 @@ fn Blog(cx: Scope) -> Element {
     }
 }
 
-#[inline_props]
 fn BlogList(cx: Scope) -> Element {
     render! {
         h2 { "Choose a post" }

+ 3 - 25
packages/router-macro/src/layout.rs

@@ -1,5 +1,5 @@
 use proc_macro2::TokenStream;
-use quote::{format_ident, quote};
+use quote::quote;
 use syn::Path;
 
 use crate::nest::{Nest, NestId};
@@ -10,25 +10,20 @@ pub struct LayoutId(pub usize);
 #[derive(Debug)]
 pub struct Layout {
     pub comp: Path,
-    pub props_name: Path,
     pub active_nests: Vec<NestId>,
 }
 
 impl Layout {
     pub fn routable_match(&self, nests: &[Nest]) -> TokenStream {
-        let props_name = &self.props_name;
         let comp_name = &self.comp;
-        let name_str = self.comp.segments.last().unwrap().ident.to_string();
         let dynamic_segments = self
             .active_nests
             .iter()
             .flat_map(|id| nests[id.0].dynamic_segments());
 
         quote! {
-            let comp = #props_name { #(#dynamic_segments,)* };
-            let dynamic = cx.component(#comp_name, comp, #name_str);
             render! {
-                dynamic
+                #comp_name { #(#dynamic_segments: #dynamic_segments,)* }
             }
         }
     }
@@ -40,23 +35,6 @@ impl Layout {
         let _ = input.parse::<syn::Token![,]>();
         let comp: Path = input.parse()?;
 
-        // Then parse the props name
-        let _ = input.parse::<syn::Token![,]>();
-        let props_name = input.parse::<Path>().unwrap_or_else(|_| {
-            let last = format_ident!("{}Props", comp.segments.last().unwrap().ident.to_string());
-            let mut segments = comp.segments.clone();
-            segments.pop();
-            segments.push(last.into());
-            Path {
-                leading_colon: None,
-                segments,
-            }
-        });
-
-        Ok(Self {
-            comp,
-            props_name,
-            active_nests,
-        })
+        Ok(Self { comp, active_nests })
     }
 }

+ 11 - 13
packages/router-macro/src/lib.rs

@@ -43,8 +43,8 @@ mod segment;
 /// #[rustfmt::skip]
 /// #[derive(Clone, Debug, PartialEq, Routable)]
 /// enum Route {
-///     // Define routes with the route macro. If the name of the component is not the same as the variant, you can specify it as the second parameter and the props type as the third
-///     #[route("/", IndexComponent, ComponentProps)]
+///     // Define routes with the route macro. If the name of the component is not the same as the variant, you can specify it as the second parameter
+///     #[route("/", IndexComponent)]
 ///     Index {},
 ///     // Nests with parameters have types taken from child routes
 ///     // Everything inside the nest has the added parameter `user_id: usize`
@@ -52,7 +52,7 @@ mod segment;
 ///         // All children of layouts will be rendered inside the Outlet in the layout component
 ///         // Creates a Layout UserFrame that has the parameter `user_id: usize`
 ///         #[layout(UserFrame)]
-///             // If there is a component with the name Route1 and props with the name Route1Props, you do not need to pass in the component and type
+///             // If there is a component with the name Route1, you do not need to pass in the component name
 ///             #[route("/:dynamic?:query")]
 ///             Route1 {
 ///                 // The type is taken from the first instance of the dynamic parameter
@@ -78,12 +78,11 @@ mod segment;
 /// }
 /// ```
 ///
-/// # `#[route("path", component, props)]`
+/// # `#[route("path", component)]`
 ///
 /// The `#[route]` attribute is used to define a route. It takes up to 3 parameters:
 /// - `path`: The path to the enum variant (relative to the parent nest)
 /// - (optional) `component`: The component to render when the route is matched. If not specified, the name of the variant is used
-/// - (optional) `props`: The props type for the component. If not specified, the name of the variant with `Props` appended is used
 ///
 /// Routes are the most basic attribute. They allow you to define a route and the component to render when the route is matched. The component must take all dynamic parameters of the route and all parent nests.
 /// The next variant will be tied to the component. If you link to that variant, the component will be rendered.
@@ -91,9 +90,9 @@ mod segment;
 /// ```rust, skip
 /// #[derive(Clone, Debug, PartialEq, Routable)]
 /// enum Route {
-///     // Define routes that renders the IndexComponent that takes the IndexProps
+///     // Define routes that renders the IndexComponent
 ///     // The Index component will be rendered when the route is matched (e.g. when the user navigates to /)
-///     #[route("/", Index, IndexProps)]
+///     #[route("/", Index)]
 ///     Index {},
 /// }
 /// ```
@@ -109,7 +108,7 @@ mod segment;
 /// enum Route {
 ///     // Redirects the /:id route to the Index route
 ///     #[redirect("/:id", |_: usize| Route::Index {})]
-///     #[route("/", Index, IndexProps)]
+///     #[route("/", Index)]
 ///     Index {},
 /// }
 /// ```
@@ -131,7 +130,7 @@ mod segment;
 ///         // This is at /blog/:id
 ///         #[redirect("/:id", |_: usize| Route::Index {})]
 ///         // This is at /blog
-///         #[route("/", Index, IndexProps)]
+///         #[route("/", Index)]
 ///         Index {},
 /// }
 /// ```
@@ -147,7 +146,7 @@ mod segment;
 ///         // This is at /blog/:id
 ///         #[redirect("/:id", |_: usize| Route::Index {})]
 ///         // This is at /blog
-///         #[route("/", Index, IndexProps)]
+///         #[route("/", Index)]
 ///         Index {},
 ///     // Ends the nest
 ///     #[end_nest]
@@ -161,7 +160,6 @@ mod segment;
 ///
 /// The `#[layout]` attribute is used to define a layout. It takes 2 parameters:
 /// - `component`: The component to render when the route is matched. If not specified, the name of the variant is used
-/// - (optional) `props`: The props type for the component. If not specified, the name of the variant with `Props` appended is used
 ///
 /// The layout component allows you to wrap all children of the layout in a component. The child routes are rendered in the Outlet of the layout component. The layout component must take all dynamic parameters of the nests it is nested in.
 ///
@@ -171,7 +169,7 @@ mod segment;
 ///     #[layout(BlogFrame)]
 ///         #[redirect("/:id", |_: usize| Route::Index {})]
 ///         // Index will be rendered in the Outlet of the BlogFrame component
-///         #[route("/", Index, IndexProps)]
+///         #[route("/", Index)]
 ///         Index {},
 /// }
 /// ```
@@ -186,7 +184,7 @@ mod segment;
 ///     #[layout(BlogFrame)]
 ///         #[redirect("/:id", |_: usize| Route::Index {})]
 ///         // Index will be rendered in the Outlet of the BlogFrame component
-///         #[route("/", Index, IndexProps)]
+///         #[route("/", Index)]
 ///         Index {},
 ///     // Ends the layout
 ///     #[end_layout]

+ 5 - 25
packages/router-macro/src/route.rs

@@ -21,7 +21,6 @@ use crate::segment::RouteSegment;
 struct RouteArgs {
     route: LitStr,
     comp_name: Option<Path>,
-    props_name: Option<Path>,
 }
 
 impl Parse for RouteArgs {
@@ -34,10 +33,6 @@ impl Parse for RouteArgs {
                 let _ = input.parse::<syn::Token![,]>();
                 input.parse().ok()
             },
-            props_name: {
-                let _ = input.parse::<syn::Token![,]>();
-                input.parse().ok()
-            },
         })
     }
 }
@@ -83,22 +78,8 @@ impl Route {
             Some(attr) => {
                 let args = attr.parse_args::<RouteArgs>()?;
                 let comp_name = args.comp_name.unwrap_or_else(|| parse_quote!(#route_name));
-                let props_name = args.props_name.unwrap_or_else(|| {
-                    let last = format_ident!(
-                        "{}Props",
-                        comp_name.segments.last().unwrap().ident.to_string()
-                    );
-                    let mut segments = comp_name.segments.clone();
-                    segments.pop();
-                    segments.push(last.into());
-                    Path {
-                        leading_colon: None,
-                        segments,
-                    }
-                });
                 ty = RouteType::Leaf {
                     component: comp_name,
-                    props: props_name,
                 };
                 route = args.route.value();
             }
@@ -227,7 +208,6 @@ impl Route {
 
     pub fn routable_match(&self, layouts: &[Layout], nests: &[Nest]) -> TokenStream2 {
         let name = &self.route_name;
-        let name_str = name.to_string();
 
         let mut tokens = TokenStream2::new();
 
@@ -261,16 +241,16 @@ impl Route {
                     }
                 }
             }
-            RouteType::Leaf { component, props } => {
+            RouteType::Leaf { component } => {
                 let dynamic_segments = self.dynamic_segments();
                 let dynamic_segments_from_route = self.dynamic_segments();
                 quote! {
                     #[allow(unused)]
                     (#last_index, Self::#name { #(#dynamic_segments,)* }) => {
-                        let comp = #props { #(#dynamic_segments_from_route,)* };
-                        let dynamic = cx.component(#component, comp, #name_str);
                         render! {
-                            dynamic
+                            #component {
+                                #(#dynamic_segments_from_route: #dynamic_segments_from_route,)*
+                            }
                         }
                     }
                 }
@@ -364,5 +344,5 @@ impl Route {
 #[derive(Debug)]
 pub(crate) enum RouteType {
     Child(Field),
-    Leaf { component: Path, props: Path },
+    Leaf { component: Path },
 }

+ 2 - 0
packages/router/src/components/default_errors.rs

@@ -1,9 +1,11 @@
+#[allow(deprecated)]
 use crate::hooks::use_router;
 use dioxus::prelude::*;
 
 /// The default component to render when an external navigation fails.
 #[allow(non_snake_case)]
 pub fn FailureExternalNavigation(cx: Scope) -> Element {
+    #[allow(deprecated)]
     let router = use_router(cx);
 
     render! {

+ 7 - 10
packages/router/src/components/link.rs

@@ -1,5 +1,6 @@
 use std::any::Any;
 use std::fmt::Debug;
+use std::rc::Rc;
 
 use dioxus::prelude::*;
 use log::error;
@@ -9,25 +10,24 @@ use crate::prelude::Routable;
 use crate::utils::use_router_internal::use_router_internal;
 
 /// Something that can be converted into a [`NavigationTarget`].
+#[derive(Clone)]
 pub enum IntoRoutable {
     /// A raw string target.
     FromStr(String),
     /// A internal target.
-    Route(Box<dyn Any>),
+    Route(Rc<dyn Any>),
 }
 
 impl<R: Routable> From<R> for IntoRoutable {
     fn from(value: R) -> Self {
-        IntoRoutable::Route(Box::new(value) as Box<dyn Any>)
+        IntoRoutable::Route(Rc::new(value) as Rc<dyn Any>)
     }
 }
 
 impl<R: Routable> From<NavigationTarget<R>> for IntoRoutable {
     fn from(value: NavigationTarget<R>) -> Self {
         match value {
-            NavigationTarget::Internal(route) => {
-                IntoRoutable::Route(Box::new(route) as Box<dyn Any>)
-            }
+            NavigationTarget::Internal(route) => IntoRoutable::Route(Rc::new(route) as Rc<dyn Any>),
             NavigationTarget::External(url) => IntoRoutable::FromStr(url),
         }
     }
@@ -197,10 +197,7 @@ pub fn Link<'a>(cx: Scope<'a, LinkProps<'a>>) -> Element {
         IntoRoutable::FromStr(url) => url.to_string(),
         IntoRoutable::Route(route) => router.any_route_to_string(&**route),
     };
-    let parsed_route: NavigationTarget<Box<dyn Any>> = match router.route_from_str(&href) {
-        Ok(route) => NavigationTarget::Internal(route),
-        Err(err) => NavigationTarget::External(err),
-    };
+    let parsed_route: NavigationTarget<Rc<dyn Any>> = router.resolve_into_routable(to.clone());
     let ac = active_class
         .and_then(|active_class| (href == current_url).then(|| format!(" {active_class}")))
         .unwrap_or_default();
@@ -219,7 +216,7 @@ pub fn Link<'a>(cx: Scope<'a, LinkProps<'a>>) -> Element {
     let do_default = onclick.is_none() || !onclick_only;
     let action = move |event| {
         if do_default && is_router_nav {
-            router.push_any(router.resolve_into_routable(to));
+            router.push_any(router.resolve_into_routable(to.clone()));
         }
 
         if let Some(handler) = onclick {

+ 2 - 6
packages/router/src/contexts/navigator.rs

@@ -35,17 +35,13 @@ impl Navigator {
     ///
     /// The previous location will be available to go back to.
     pub fn push(&self, target: impl Into<IntoRoutable>) -> Option<ExternalNavigationFailure> {
-        let target = target.into();
-        let as_any_navigation_target = self.0.resolve_into_routable(&target);
-        self.0.push_any(as_any_navigation_target)
+        self.0.push(target)
     }
 
     /// Replace the current location.
     ///
     /// The previous location will **not** be available to go back to.
     pub fn replace(&self, target: impl Into<IntoRoutable>) -> Option<ExternalNavigationFailure> {
-        let target = target.into();
-        let as_any_navigation_target = self.0.resolve_into_routable(&target);
-        self.0.replace_any(as_any_navigation_target)
+        self.0.replace(target)
     }
 }

+ 34 - 51
packages/router/src/contexts/router.rs

@@ -1,6 +1,7 @@
 use std::{
     any::Any,
     collections::HashSet,
+    rc::Rc,
     sync::{Arc, RwLock, RwLockWriteGuard},
 };
 
@@ -18,9 +19,10 @@ use crate::{
 pub struct ExternalNavigationFailure(String);
 
 /// A function the router will call after every routing update.
-pub(crate) type RoutingCallback<R> = Arc<dyn Fn(LinkContext<R>) -> Option<NavigationTarget<R>>>;
+pub(crate) type RoutingCallback<R> =
+    Arc<dyn Fn(GenericRouterContext<R>) -> Option<NavigationTarget<R>>>;
 pub(crate) type AnyRoutingCallback =
-    Arc<dyn Fn(RouterContext) -> Option<NavigationTarget<Box<dyn Any>>>>;
+    Arc<dyn Fn(RouterContext) -> Option<NavigationTarget<Rc<dyn Any>>>>;
 
 struct MutableRouterState {
     /// The current prefix.
@@ -70,18 +72,18 @@ impl RouterContext {
 
             routing_callback: cfg.on_update.map(|update| {
                 Arc::new(move |ctx| {
-                    let ctx = LinkContext {
+                    let ctx = GenericRouterContext {
                         inner: ctx,
                         _marker: std::marker::PhantomData,
                     };
                     update(ctx).map(|t| match t {
                         NavigationTarget::Internal(r) => {
-                            NavigationTarget::Internal(Box::new(r) as Box<dyn Any>)
+                            NavigationTarget::Internal(Rc::new(r) as Rc<dyn Any>)
                         }
                         NavigationTarget::External(s) => NavigationTarget::External(s),
                     })
                 })
-                    as Arc<dyn Fn(RouterContext) -> Option<NavigationTarget<Box<dyn Any>>>>
+                    as Arc<dyn Fn(RouterContext) -> Option<NavigationTarget<Rc<dyn Any>>>>
             }),
 
             failure_external_navigation: cfg.failure_external_navigation,
@@ -114,7 +116,7 @@ impl RouterContext {
         myself
     }
 
-    pub(crate) fn route_from_str(&self, route: &str) -> Result<Box<dyn Any>, String> {
+    pub(crate) fn route_from_str(&self, route: &str) -> Result<Rc<dyn Any>, String> {
         let state = self.state.read().unwrap();
         state.history.parse_route(route)
     }
@@ -155,7 +157,7 @@ impl RouterContext {
 
     pub(crate) fn push_any(
         &self,
-        target: NavigationTarget<Box<dyn Any>>,
+        target: NavigationTarget<Rc<dyn Any>>,
     ) -> Option<ExternalNavigationFailure> {
         match target {
             NavigationTarget::Internal(p) => {
@@ -171,15 +173,12 @@ impl RouterContext {
     /// Push a new location.
     ///
     /// The previous location will be available to go back to.
-    pub fn push<R: Routable>(
-        &self,
-        target: impl Into<NavigationTarget<R>>,
-    ) -> Option<ExternalNavigationFailure> {
-        let target = target.into();
+    pub fn push(&self, target: impl Into<IntoRoutable>) -> Option<ExternalNavigationFailure> {
+        let target = self.resolve_into_routable(target.into());
         match target {
             NavigationTarget::Internal(p) => {
                 let mut state = self.state_mut();
-                state.history.push(Box::new(p))
+                state.history.push(Rc::new(p))
             }
             NavigationTarget::External(e) => return self.external(e),
         }
@@ -190,16 +189,13 @@ impl RouterContext {
     /// Replace the current location.
     ///
     /// The previous location will **not** be available to go back to.
-    pub fn replace<R: Routable>(
-        &self,
-        target: impl Into<NavigationTarget<R>>,
-    ) -> Option<ExternalNavigationFailure> {
-        let target = target.into();
+    pub fn replace(&self, target: impl Into<IntoRoutable>) -> Option<ExternalNavigationFailure> {
+        let target = self.resolve_into_routable(target.into());
 
         {
             let mut state = self.state_mut();
             match target {
-                NavigationTarget::Internal(p) => state.history.replace(Box::new(p)),
+                NavigationTarget::Internal(p) => state.history.replace(Rc::new(p)),
                 NavigationTarget::External(e) => return self.external(e),
             }
         }
@@ -207,31 +203,17 @@ impl RouterContext {
         self.change_route()
     }
 
-    pub(crate) fn replace_any(
-        &self,
-        target: NavigationTarget<Box<dyn Any>>,
-    ) -> Option<ExternalNavigationFailure> {
-        match target {
-            NavigationTarget::Internal(p) => {
-                let mut state = self.state_mut();
-                state.history.replace(p)
-            }
-            NavigationTarget::External(e) => return self.external(e),
-        }
-
-        self.change_route()
-    }
-
     /// The route that is currently active.
     pub fn current<R: Routable>(&self) -> R {
-        *self
-            .state
+        self.state
             .read()
             .unwrap()
             .history
             .current_route()
             .downcast::<R>()
             .unwrap()
+            .as_ref()
+            .clone()
     }
 
     /// The route that is currently active.
@@ -245,17 +227,18 @@ impl RouterContext {
 
     pub(crate) fn resolve_into_routable(
         &self,
-        into_routable: &IntoRoutable,
-    ) -> NavigationTarget<Box<dyn Any>> {
-        let href = match into_routable {
-            IntoRoutable::FromStr(url) => url.to_string(),
-            IntoRoutable::Route(route) => self.any_route_to_string(&**route),
-        };
-        let parsed_route: NavigationTarget<Box<dyn Any>> = match self.route_from_str(&href) {
-            Ok(route) => NavigationTarget::Internal(route),
-            Err(err) => NavigationTarget::External(err),
-        };
-        parsed_route
+        into_routable: IntoRoutable,
+    ) -> NavigationTarget<Rc<dyn Any>> {
+        match into_routable {
+            IntoRoutable::FromStr(url) => {
+                let parsed_route: NavigationTarget<Rc<dyn Any>> = match self.route_from_str(&url) {
+                    Ok(route) => NavigationTarget::Internal(route),
+                    Err(err) => NavigationTarget::External(err),
+                };
+                parsed_route
+            }
+            IntoRoutable::Route(route) => NavigationTarget::Internal(route),
+        }
     }
 
     /// The prefix that is currently active.
@@ -332,12 +315,12 @@ impl RouterContext {
     }
 }
 
-pub struct LinkContext<R> {
+pub struct GenericRouterContext<R> {
     inner: RouterContext,
     _marker: std::marker::PhantomData<R>,
 }
 
-impl<R> LinkContext<R>
+impl<R> GenericRouterContext<R>
 where
     R: Routable,
 {
@@ -374,7 +357,7 @@ where
         &self,
         target: impl Into<NavigationTarget<R>>,
     ) -> Option<ExternalNavigationFailure> {
-        self.inner.push(target)
+        self.inner.push(target.into())
     }
 
     /// Replace the current location.
@@ -384,7 +367,7 @@ where
         &self,
         target: impl Into<NavigationTarget<R>>,
     ) -> Option<ExternalNavigationFailure> {
-        self.inner.replace(target)
+        self.inner.replace(target.into())
     }
 
     /// The route that is currently active.

+ 15 - 13
packages/router/src/history/mod.rs

@@ -10,7 +10,7 @@
 //! 1) [`MemoryHistory`] for desktop/mobile/ssr platforms
 //! 2) [`WebHistory`] for web platforms
 
-use std::{any::Any, sync::Arc};
+use std::{any::Any, rc::Rc, sync::Arc};
 
 mod memory;
 pub use memory::*;
@@ -279,13 +279,13 @@ pub trait HistoryProvider<R: Routable> {
 }
 
 pub(crate) trait AnyHistoryProvider {
-    fn parse_route(&self, route: &str) -> Result<Box<dyn Any>, String>;
+    fn parse_route(&self, route: &str) -> Result<Rc<dyn Any>, String>;
 
     #[must_use]
     fn accepts_type_id(&self, type_id: &std::any::TypeId) -> bool;
 
     #[must_use]
-    fn current_route(&self) -> Box<dyn Any>;
+    fn current_route(&self) -> Rc<dyn Any>;
 
     #[must_use]
     fn current_prefix(&self) -> Option<String> {
@@ -306,9 +306,9 @@ pub(crate) trait AnyHistoryProvider {
 
     fn go_forward(&mut self);
 
-    fn push(&mut self, route: Box<dyn Any>);
+    fn push(&mut self, route: Rc<dyn Any>);
 
-    fn replace(&mut self, path: Box<dyn Any>);
+    fn replace(&mut self, path: Rc<dyn Any>);
 
     #[allow(unused_variables)]
     fn external(&mut self, url: String) -> bool {
@@ -345,19 +345,19 @@ where
     <R as std::str::FromStr>::Err: std::fmt::Display,
     H: HistoryProvider<R>,
 {
-    fn parse_route(&self, route: &str) -> Result<Box<dyn Any>, String> {
+    fn parse_route(&self, route: &str) -> Result<Rc<dyn Any>, String> {
         R::from_str(route)
             .map_err(|err| err.to_string())
-            .map(|route| Box::new(route) as Box<dyn Any>)
+            .map(|route| Rc::new(route) as Rc<dyn Any>)
     }
 
     fn accepts_type_id(&self, type_id: &std::any::TypeId) -> bool {
         type_id == &std::any::TypeId::of::<R>()
     }
 
-    fn current_route(&self) -> Box<dyn Any> {
+    fn current_route(&self) -> Rc<dyn Any> {
         let route = self.inner.current_route();
-        Box::new(route)
+        Rc::new(route)
     }
 
     fn current_prefix(&self) -> Option<String> {
@@ -380,12 +380,14 @@ where
         self.inner.go_forward()
     }
 
-    fn push(&mut self, route: Box<dyn Any>) {
-        self.inner.push(*route.downcast().unwrap())
+    fn push(&mut self, route: Rc<dyn Any>) {
+        self.inner
+            .push(route.downcast::<R>().unwrap().as_ref().clone())
     }
 
-    fn replace(&mut self, path: Box<dyn Any>) {
-        self.inner.replace(*path.downcast().unwrap())
+    fn replace(&mut self, route: Rc<dyn Any>) {
+        self.inner
+            .replace(route.downcast::<R>().unwrap().as_ref().clone())
     }
 
     fn external(&mut self, url: String) -> bool {

+ 1 - 0
packages/router/src/hooks/use_router.rs

@@ -2,6 +2,7 @@ use dioxus::prelude::ScopeState;
 
 use crate::{prelude::RouterContext, utils::use_router_internal::use_router_internal};
 
+#[deprecated = "prefer the use_navigator or use_route functions"]
 /// A hook that provides access to information about the router.
 pub fn use_router(cx: &ScopeState) -> &RouterContext {
     use_router_internal(cx)

+ 1 - 1
packages/router/src/lib.rs

@@ -42,7 +42,7 @@ mod history;
 /// Hooks for interacting with the router in components.
 pub mod hooks {
     mod use_router;
-    pub(crate) use use_router::*;
+    pub use use_router::*;
 
     mod use_route;
     pub use use_route::*;

+ 1 - 1
packages/router/src/router_cfg.rs

@@ -112,7 +112,7 @@ where
     /// Defaults to [`None`].
     pub fn on_update(
         self,
-        callback: impl Fn(LinkContext<R>) -> Option<NavigationTarget<R>> + 'static,
+        callback: impl Fn(GenericRouterContext<R>) -> Option<NavigationTarget<R>> + 'static,
     ) -> Self {
         Self {
             on_update: Some(Arc::new(callback)),