1
0

use_route.rs 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. use async_rwlock::RwLockReadGuard;
  2. use dioxus::{core::Component, prelude::ScopeState};
  3. use dioxus_router_core::RouterState;
  4. use crate::{utils::use_router_internal::use_router_internal};
  5. /// A hook that provides access to information about the current routing location.
  6. ///
  7. /// # Return values
  8. /// - [`RouterError::NotInsideRouter`], when the calling component is not nested within another
  9. /// component calling the [`use_router`] hook.
  10. /// - Otherwise [`Ok`].
  11. ///
  12. /// # Important usage information
  13. /// Make sure to [`drop`] the returned [`RwLockReadGuard`] when done rendering. Otherwise the router
  14. /// will be frozen.
  15. ///
  16. /// # Panic
  17. /// - When the calling component is not nested within another component calling the [`use_router`]
  18. /// hook, but only in debug builds.
  19. ///
  20. /// # Example
  21. /// ```rust
  22. /// # use dioxus::prelude::*;
  23. /// # use dioxus_router::{history::*, prelude::*};
  24. /// fn App(cx: Scope) -> Element {
  25. /// use_router(
  26. /// &cx,
  27. /// &|| RouterConfiguration {
  28. /// synchronous: true, // asynchronicity not needed for doc test
  29. /// history: Box::new(MemoryHistory::with_initial_path("/some/path").unwrap()),
  30. /// ..Default::default()
  31. /// },
  32. /// &|| Segment::empty()
  33. /// );
  34. ///
  35. /// render! {
  36. /// h1 { "App" }
  37. /// Content { }
  38. /// }
  39. /// }
  40. ///
  41. /// fn Content(cx: Scope) -> Element {
  42. /// let state = use_route(&cx)?;
  43. /// let path = state.path.clone();
  44. ///
  45. /// render! {
  46. /// h2 { "Current Path" }
  47. /// p { "{path}" }
  48. /// }
  49. /// }
  50. /// #
  51. /// # let mut vdom = VirtualDom::new(App);
  52. /// # let _ = vdom.rebuild();
  53. /// # assert_eq!(dioxus_ssr::render(&vdom), "<h1>App</h1><h2>Current Path</h2><p>/some/path</p>")
  54. /// ```
  55. ///
  56. /// [`use_router`]: crate::hooks::use_router
  57. pub fn use_route(cx: &ScopeState) -> Option<RwLockReadGuard<RouterState<Component>>> {
  58. match use_router_internal(cx) {
  59. Some(r) => loop {
  60. if let Some(s) = r.state.try_read() {
  61. break Some(s);
  62. }
  63. },
  64. None => {
  65. #[cfg(debug_assertions)]
  66. panic!("`use_route` must have access to a parent router");
  67. #[allow(unreachable_code)]
  68. None
  69. }
  70. }
  71. }