Kaede Hoshikawa 485a1b8c4a
Function Components & Hooks V2 (#2401)
* Make a use_hook hook with the new Hook trait.

* Implement Lifetime.

* Rewrites function signature.

* Only apply lifetime if there're other lifetimes.

* Cleanup signature rewrite logic.

* Rewrite hook body.

* Port some built-in hooks.

* Finish porting all built-in hooks.

* Port tests.

* Fix tests.

* Migrate to macro-based hooks.

* Fix HookContext, add tests on non-possible locations.

* Fix stderr for trybuild.

* Add 1 more test case.

* Adjust doc location.

* Pretty print hook signature.

* Fix Items & std::ops::Fn*.

* Add use_memo.

* Optimise Implementation of hooks.

* Use Box to capture function value only.

* Detect whether needs boxing.

* Add args if boxing not needed.

* Enforce hook number.

* Deduplicate use_effect.

* Optimise Implementation.

* Update documentation.

* Fix website test. Strip BoxedHook implementation from it.

* Allow doc string.

* Workaround doc tests.

* Optimise codebase & documentation.

* Fix website test.

* Reduce implementation complexity.

* Destructor is no more.

* Documentation and macros.

* Reduce heap allocation and hook complexity.

* Remove Queue as well.

* Prefer Generics.

* Fix typo.

* Remove more allocations.

* Add comments.

* Remove outdated comment.

* Bare Function Pointer for better code size.
2022-01-28 11:51:37 +02:00

41 lines
1.0 KiB
Rust

//! Hooks to access router state and navigate between pages.
use crate::history::*;
use crate::navigator::Navigator;
use crate::routable::Routable;
use crate::router::{LocationContext, NavigatorContext};
use yew::prelude::*;
/// A hook to access the [`Navigator`].
#[hook]
pub fn use_navigator() -> Option<Navigator> {
use_context::<NavigatorContext>().map(|m| m.navigator())
}
/// A hook to access the current [`Location`].
#[hook]
pub fn use_location() -> Option<Location> {
Some(use_context::<LocationContext>()?.location())
}
/// A hook to access the current route.
///
/// This hook will return [`None`] if there's no available location or none of the routes match.
///
/// # Note
///
/// If your `Routable` has a `#[not_found]` route, you can use `.unwrap_or_default()` instead of
/// `.unwrap()` to unwrap.
#[hook]
pub fn use_route<R>() -> Option<R>
where
R: Routable + 'static,
{
let navigator = use_navigator()?;
let location = use_location()?;
let path = navigator.strip_basename(location.path().into());
R::recognize(&path)
}