use_router.rs 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. use async_rwlock::RwLockReadGuard;
  2. use dioxus::{core::Component, prelude::*};
  3. use dioxus_router_core::{
  4. history::{HistoryProvider, MemoryHistory},
  5. routes::{ContentAtom, Segment},
  6. RouterService, RouterState, RoutingCallback,
  7. };
  8. use crate::{
  9. contexts::router::RouterContext,
  10. prelude::{
  11. comp,
  12. default_errors::{
  13. FailureExternalNavigation, FailureNamedNavigation, FailureRedirectionLimit,
  14. },
  15. },
  16. };
  17. pub fn use_router<'a>(
  18. cx: &'a ScopeState,
  19. cfg: &dyn Fn() -> RouterConfiguration,
  20. content: &dyn Fn() -> Segment<Component>,
  21. ) -> (RwLockReadGuard<'a, RouterState<Component>>, ()) {
  22. let (service, state, sender) = cx.use_hook(|| {
  23. let cfg = cfg();
  24. let content = content();
  25. let (mut service, sender, state) = RouterService::new(
  26. content,
  27. cfg.history,
  28. cx.schedule_update_any(),
  29. cfg.on_update,
  30. cfg.failure_external_navigation,
  31. cfg.failure_named_navigation,
  32. cfg.failure_redirection_limit,
  33. );
  34. cx.provide_context(RouterContext {
  35. state: state.clone(),
  36. sender: sender.clone(),
  37. });
  38. (
  39. if cfg.synchronous {
  40. Some(service)
  41. } else {
  42. cx.spawn(async move { service.run().await });
  43. None
  44. },
  45. state,
  46. sender,
  47. )
  48. });
  49. if let Some(service) = service {
  50. service.run_current();
  51. }
  52. (
  53. loop {
  54. if let Some(state) = state.try_read() {
  55. break state;
  56. }
  57. },
  58. (),
  59. )
  60. }
  61. pub struct RouterConfiguration {
  62. pub failure_external_navigation: ContentAtom<Component>,
  63. pub failure_named_navigation: ContentAtom<Component>,
  64. pub failure_redirection_limit: ContentAtom<Component>,
  65. pub history: Box<dyn HistoryProvider>,
  66. pub on_update: Option<RoutingCallback<Component>>,
  67. pub synchronous: bool,
  68. }
  69. impl Default for RouterConfiguration {
  70. fn default() -> Self {
  71. Self {
  72. failure_external_navigation: comp(FailureExternalNavigation),
  73. failure_named_navigation: comp(FailureNamedNavigation),
  74. failure_redirection_limit: comp(FailureRedirectionLimit),
  75. history: Box::new(MemoryHistory::default()),
  76. on_update: None,
  77. synchronous: false,
  78. }
  79. }
  80. }