add a way to subscribe to a dependency tuple for the use_resource hook
This commit is contained in:
1 parent
41809f9a1b
commit
2bbc609082
3 files changed
+73
-40
No files matched your search
@@ -1,7 +1,7 @@
|
||||
/// A dependency is a trait that can be used to determine if a effect or selector should be re-run.
|
||||
pub trait Dependency: Sized + Clone {
|
||||
/// The output of the dependency
|
||||
type Out: Clone + PartialEq;
|
||||
type Out: Clone + PartialEq + 'static;
|
||||
/// Returns the output of the dependency.
|
||||
fn out(&self) -> Self::Out;
|
||||
/// Returns true if the dependency has changed.
|
||||
@@ -16,10 +16,10 @@ impl Dependency for () {
|
||||
}
|
||||
|
||||
/// A dependency is a trait that can be used to determine if a effect or selector should be re-run.
|
||||
pub trait Dep: 'static + PartialEq + Clone {}
|
||||
impl<T> Dep for T where T: 'static + PartialEq + Clone {}
|
||||
pub trait DependencyElement: 'static + PartialEq + Clone {}
|
||||
impl<T> DependencyElement for T where T: 'static + PartialEq + Clone {}
|
||||
|
||||
impl<A: Dep> Dependency for &A {
|
||||
impl<A: DependencyElement> Dependency for &A {
|
||||
type Out = A;
|
||||
fn out(&self) -> Self::Out {
|
||||
(*self).clone()
|
||||
@@ -33,7 +33,7 @@ macro_rules! impl_dep {
|
||||
impl< $($el),* > Dependency for ($(&$el,)*)
|
||||
where
|
||||
$(
|
||||
$el: Dep
|
||||
$el: DependencyElement
|
||||
),*
|
||||
{
|
||||
type Out = ($($el,)*);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#![allow(missing_docs)]
|
||||
|
||||
use crate::{use_callback, use_signal, UseCallback};
|
||||
use crate::{dependency, use_callback, use_signal, UseCallback};
|
||||
use dioxus_core::prelude::*;
|
||||
use dioxus_core::{
|
||||
prelude::{spawn, use_hook},
|
||||
@@ -125,6 +125,46 @@ pub enum UseResourceState {
|
||||
}
|
||||
|
||||
impl<T> Resource<T> {
|
||||
/// Adds an explicit dependency to the resource. If the dependency changes, the resource's future will rerun.
|
||||
///
|
||||
/// Signals will automatically be added as dependencies, so you don't need to call this method for them.
|
||||
///
|
||||
/// NOTE: You must follow the rules of hooks when calling this method.
|
||||
///
|
||||
/// ```rust
|
||||
/// # use dioxus::prelude::*;
|
||||
/// # async fn sleep(delay: u32) {}
|
||||
///
|
||||
/// #[component]
|
||||
/// fn Comp(delay: u32) -> Element {
|
||||
/// // Because the resource subscribes to `delay` by adding it as a dependency, the resource's future will rerun every time `delay` changes.
|
||||
/// let current_weather = use_resource(move || async move {
|
||||
/// sleep(delay).await;
|
||||
/// "Sunny"
|
||||
/// })
|
||||
/// .use_dependencies((&delay,));
|
||||
///
|
||||
/// rsx! {
|
||||
/// // the value of the resource can be polled to
|
||||
/// // conditionally render elements based off if it's future
|
||||
/// // finished (Some(Ok(_)), errored Some(Err(_)),
|
||||
/// // or is still running (None)
|
||||
/// match &*current_weather.read_unchecked() {
|
||||
/// Some(weather) => rsx! { "{weather}" },
|
||||
/// None => rsx! { p { "Loading..." } }
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
pub fn use_dependencies(self, dependency: impl dependency::Dependency) -> Self {
|
||||
let mut dependencies_signal = use_signal(|| dependency.out());
|
||||
let changed = { dependency.changed(&*dependencies_signal.read()) };
|
||||
if changed {
|
||||
dependencies_signal.set(dependency.out());
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
/// Restart the resource's future.
|
||||
///
|
||||
/// Will not cancel the previous future, but will ignore any values that it
|
||||
|
||||
Reference in new issue
Block a user