mirror of
https://github.com/yewstack/yew.git
synced 2025-12-08 21:26:25 +00:00
Introduce a dedicated use_force_update hook (#2586)
* introduce a dedicated use_force_update hook * fix doc links
This commit is contained in:
parent
ae26885589
commit
6992a454e3
@ -1,6 +1,7 @@
|
||||
mod use_callback;
|
||||
mod use_context;
|
||||
mod use_effect;
|
||||
mod use_force_update;
|
||||
mod use_memo;
|
||||
mod use_reducer;
|
||||
mod use_ref;
|
||||
@ -9,6 +10,7 @@ mod use_state;
|
||||
pub use use_callback::*;
|
||||
pub use use_context::*;
|
||||
pub use use_effect::*;
|
||||
pub use use_force_update::*;
|
||||
pub use use_memo::*;
|
||||
pub use use_reducer::*;
|
||||
pub use use_ref::*;
|
||||
|
||||
84
packages/yew/src/functional/hooks/use_force_update.rs
Normal file
84
packages/yew/src/functional/hooks/use_force_update.rs
Normal file
@ -0,0 +1,84 @@
|
||||
use super::{Hook, HookContext};
|
||||
use crate::functional::ReRender;
|
||||
use std::fmt;
|
||||
|
||||
/// A handle which can be used to force a re-render of the associated
|
||||
/// function component.
|
||||
#[derive(Clone)]
|
||||
pub struct UseForceUpdate {
|
||||
trigger: ReRender,
|
||||
}
|
||||
|
||||
impl fmt::Debug for UseForceUpdate {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("UseForceUpdate").finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl UseForceUpdate {
|
||||
/// Trigger an unconditional re-render of the associated function component
|
||||
pub fn force_update(&self) {
|
||||
(self.trigger)()
|
||||
}
|
||||
}
|
||||
|
||||
// #![feature(fn_traits)] // required nightly feature to make UseForceUpdate callable directly
|
||||
// impl Fn<()> for UseForceUpdate {
|
||||
// extern "rust-call" fn call(&self, _args: ()) {
|
||||
// self.force_update()
|
||||
// }
|
||||
// }
|
||||
|
||||
/// This hook is used to manually force a function component to re-render.
|
||||
///
|
||||
/// Try to use more specialized hooks, such as [`use_state`] and [`use_reducer`].
|
||||
/// This hook should only be used when your component depends on external state where you
|
||||
/// can't subscribe to changes, or as a low-level primitive to enable such a subscription-based
|
||||
/// approach.
|
||||
///
|
||||
/// For example, a large externally managed cache, such as a app-wide cache for GraphQL data
|
||||
/// should not rerender every component whenever new data arrives, but only those where a query
|
||||
/// changed.
|
||||
///
|
||||
/// If the state of your component is not shared, you should need to use this hook.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// This example implements a silly, manually updated display of the current time. The component
|
||||
/// is rerendered every time the button is clicked. You should usually use a timeout and `use_state`
|
||||
/// to automatically trigger a re-render every second without having to use this hook.
|
||||
///
|
||||
/// ```rust
|
||||
/// # use yew::prelude::*;
|
||||
///
|
||||
/// #[function_component]
|
||||
/// fn ManuallyUpdatedDate() -> Html {
|
||||
/// let trigger = use_force_update();
|
||||
/// let onclick = use_state(move || Callback::from(move |_| trigger.force_update()));
|
||||
/// let last_update = js_sys::Date::new_0().to_utc_string();
|
||||
/// html! {
|
||||
/// <div>
|
||||
/// <button onclick={&*onclick}>{"Update now!"}</button>
|
||||
/// <p>{"Last updated: "}{last_update}</p>
|
||||
/// </div>
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// [`use_state`]: super::use_state()
|
||||
/// [`use_reducer`]: super::use_reducer()
|
||||
pub fn use_force_update() -> impl Hook<Output = UseForceUpdate> {
|
||||
struct UseRerenderHook;
|
||||
|
||||
impl Hook for UseRerenderHook {
|
||||
type Output = UseForceUpdate;
|
||||
|
||||
fn run(self, ctx: &mut HookContext) -> Self::Output {
|
||||
UseForceUpdate {
|
||||
trigger: ctx.re_render.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UseRerenderHook
|
||||
}
|
||||
@ -36,6 +36,7 @@ Yew comes with the following predefined Hooks:
|
||||
- [`use_effect`](./use-effect.mdx)
|
||||
- [`use_effect_with_deps`](./use-effect.mdx#use_effect_with_deps)
|
||||
- [`use_context`](./use-context.mdx)
|
||||
- [`use_force_update`](./use-force-update)
|
||||
|
||||
### Custom Hooks
|
||||
|
||||
|
||||
@ -0,0 +1,19 @@
|
||||
---
|
||||
title: 'use_force_update'
|
||||
---
|
||||
|
||||
`use_force_update` is a low-level hook specialized to triggering a re-render of a function component.
|
||||
Usually, this re-render is triggered automatically by the hook holding your data, for example when
|
||||
changing the data in a handle returned from [`use_state`](./use-state).
|
||||
|
||||
::: caution
|
||||
|
||||
Often, using this hook means you are doing something wrong and should use one of the other hooks,
|
||||
for example [`use_reducer`](./use-reducer) is a great way to track changing data.
|
||||
|
||||
:::
|
||||
|
||||
Use this hook when wrapping an API that doesn't expose precise subscription events for fetched data.
|
||||
You could then, at some point, invalidate your local cache of the fetched data and trigger a re-render
|
||||
to let the normal render flow of components tell you again which data to fetch, and repopulate the
|
||||
cache accordingly.
|
||||
Loading…
x
Reference in New Issue
Block a user