mirror of
https://github.com/yewstack/yew.git
synced 2025-12-08 21:26:25 +00:00
Allow functions returning unit in use_effect (#2849)
* Use TearDown trait as destructor for use_effect * Docs * no default tear_down
This commit is contained in:
parent
cffb7c5e7e
commit
0e0d6949f6
@ -2,11 +2,27 @@ use std::cell::RefCell;
|
||||
|
||||
use crate::functional::{hook, Effect, Hook, HookContext};
|
||||
|
||||
/// Trait describing the destructor of [`use_effect`] hook.
|
||||
pub trait TearDown: Sized + 'static {
|
||||
/// The function that is executed when destructor is called
|
||||
fn tear_down(self);
|
||||
}
|
||||
|
||||
impl TearDown for () {
|
||||
fn tear_down(self) {}
|
||||
}
|
||||
|
||||
impl<F: FnOnce() + 'static> TearDown for F {
|
||||
fn tear_down(self) {
|
||||
self()
|
||||
}
|
||||
}
|
||||
|
||||
struct UseEffectBase<T, F, D>
|
||||
where
|
||||
F: FnOnce(&T) -> D + 'static,
|
||||
T: 'static,
|
||||
D: FnOnce() + 'static,
|
||||
D: TearDown,
|
||||
{
|
||||
runner_with_deps: Option<(T, F)>,
|
||||
destructor: Option<D>,
|
||||
@ -18,7 +34,7 @@ impl<T, F, D> Effect for RefCell<UseEffectBase<T, F, D>>
|
||||
where
|
||||
F: FnOnce(&T) -> D + 'static,
|
||||
T: 'static,
|
||||
D: FnOnce() + 'static,
|
||||
D: TearDown,
|
||||
{
|
||||
fn rendered(&self) {
|
||||
let mut this = self.borrow_mut();
|
||||
@ -29,7 +45,7 @@ where
|
||||
}
|
||||
|
||||
if let Some(de) = this.destructor.take() {
|
||||
de();
|
||||
de.tear_down();
|
||||
}
|
||||
|
||||
let new_destructor = runner(&deps);
|
||||
@ -44,11 +60,11 @@ impl<T, F, D> Drop for UseEffectBase<T, F, D>
|
||||
where
|
||||
F: FnOnce(&T) -> D + 'static,
|
||||
T: 'static,
|
||||
D: FnOnce() + 'static,
|
||||
D: TearDown,
|
||||
{
|
||||
fn drop(&mut self) {
|
||||
if let Some(destructor) = self.destructor.take() {
|
||||
destructor()
|
||||
destructor.tear_down()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -60,13 +76,13 @@ fn use_effect_base<T, D>(
|
||||
) -> impl Hook<Output = ()>
|
||||
where
|
||||
T: 'static,
|
||||
D: FnOnce() + 'static,
|
||||
D: TearDown,
|
||||
{
|
||||
struct HookProvider<T, F, D>
|
||||
where
|
||||
F: FnOnce(&T) -> D + 'static,
|
||||
T: 'static,
|
||||
D: FnOnce() + 'static,
|
||||
D: TearDown,
|
||||
{
|
||||
runner: F,
|
||||
deps: T,
|
||||
@ -77,7 +93,7 @@ where
|
||||
where
|
||||
F: FnOnce(&T) -> D + 'static,
|
||||
T: 'static,
|
||||
D: FnOnce() + 'static,
|
||||
D: TearDown,
|
||||
{
|
||||
type Output = ();
|
||||
|
||||
@ -141,11 +157,20 @@ where
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// # Destructor
|
||||
///
|
||||
/// Any type implementing [`TearDown`] can be used as destructor, which is called when the component
|
||||
/// is re-rendered
|
||||
///
|
||||
/// ## Tip
|
||||
///
|
||||
/// The callback can return [`()`] if there is no destructor to run.
|
||||
#[hook]
|
||||
pub fn use_effect<F, D>(f: F)
|
||||
where
|
||||
F: FnOnce() -> D + 'static,
|
||||
D: FnOnce() + 'static,
|
||||
D: TearDown,
|
||||
{
|
||||
use_effect_base(|_| f(), (), |_, _| true);
|
||||
}
|
||||
@ -176,7 +201,6 @@ where
|
||||
/// use_effect_with_deps(
|
||||
/// move |_| {
|
||||
/// log!(" Is loading prop changed!");
|
||||
/// || ()
|
||||
/// },
|
||||
/// is_loading,
|
||||
/// );
|
||||
@ -201,7 +225,6 @@ where
|
||||
/// use_effect_with_deps(
|
||||
/// move |_| {
|
||||
/// log!("I got rendered, yay!");
|
||||
/// || ()
|
||||
/// },
|
||||
/// (),
|
||||
/// );
|
||||
@ -232,12 +255,18 @@ where
|
||||
/// html! { "Hello" }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Any type implementing [`TearDown`] can be used as destructor
|
||||
///
|
||||
/// ### Tip
|
||||
///
|
||||
/// The callback can return [`()`] if there is no destructor to run.
|
||||
#[hook]
|
||||
pub fn use_effect_with_deps<T, F, D>(f: F, deps: T)
|
||||
where
|
||||
T: PartialEq + 'static,
|
||||
F: FnOnce(&T) -> D + 'static,
|
||||
D: FnOnce() + 'static,
|
||||
D: TearDown,
|
||||
{
|
||||
use_effect_base(f, deps, |lhs, rhs| lhs != rhs)
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user