Jelajahi Sumber

feat: Allow using `NavigationTarget` outside router (#3633)

* feat: Allow using `NavigationTarget` outside of router

* chore: Update import

* chore: Update imports

* fmt
Marc Espin 5 bulan lalu
induk
melakukan
c5f43dd13e

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

@@ -12,3 +12,9 @@ pub fn use_router() -> RouterContext {
 pub fn router() -> RouterContext {
     dioxus_lib::prelude::consume_context()
 }
+
+/// Try to acquire the router without subscribing to updates.
+#[doc(alias = "url")]
+pub fn try_router() -> Option<RouterContext> {
+    dioxus_lib::prelude::try_consume_context()
+}

+ 15 - 9
packages/router/src/navigation.rs

@@ -7,7 +7,9 @@ use std::{
 
 use url::{ParseError, Url};
 
-use crate::{components::child_router::consume_child_route_mapping, routable::Routable, router};
+use crate::{
+    components::child_router::consume_child_route_mapping, hooks::try_router, routable::Routable,
+};
 
 impl<R: Routable> From<R> for NavigationTarget {
     fn from(value: R) -> Self {
@@ -94,20 +96,24 @@ impl<R: Routable> From<R> for NavigationTarget<R> {
 
 impl From<&str> for NavigationTarget {
     fn from(value: &str) -> Self {
-        let router = router();
-        match router.internal_route(value) {
-            true => NavigationTarget::Internal(value.to_string()),
-            false => NavigationTarget::External(value.to_string()),
+        match try_router() {
+            Some(router) => match router.internal_route(value) {
+                true => NavigationTarget::Internal(value.to_string()),
+                false => NavigationTarget::External(value.to_string()),
+            },
+            None => NavigationTarget::External(value.to_string()),
         }
     }
 }
 
 impl From<String> for NavigationTarget {
     fn from(value: String) -> Self {
-        let router = router();
-        match router.internal_route(&value) {
-            true => NavigationTarget::Internal(value),
-            false => NavigationTarget::External(value),
+        match try_router() {
+            Some(router) => match router.internal_route(&value) {
+                true => NavigationTarget::Internal(value),
+                false => NavigationTarget::External(value),
+            },
+            None => NavigationTarget::External(value.to_string()),
         }
     }
 }