switch to use_reactive

This commit is contained in:
Evan Almloff committed 2024-03-15 11:54:09 -05:00
1 parent b8c41efb54
commit df41df75d0
8 files changed
+138 -112

No files matched your search

+14 -3
View File
@@ -26,9 +26,18 @@ fn app() -> Element {
fn Child(non_reactive_prop: i32) -> Element {
let mut signal = use_signal(|| 0);
// You can manually specify the dependencies with `use_dependencies` for values that are not reactive like props
let computed =
use_memo(move || non_reactive_prop + signal()).use_dependencies((&non_reactive_prop,));
// You can manually specify the dependencies with `use_reactive` for values that are not reactive like props
let computed = use_memo(use_reactive!(
|(non_reactive_prop,)| non_reactive_prop + signal()
));
use_effect(use_reactive!(|(non_reactive_prop,)| println!(
"{}",
non_reactive_prop + signal()
)));
let fut = use_resource(use_reactive!(|(non_reactive_prop,)| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
non_reactive_prop + signal()
}));
rsx! {
button {
@@ -37,5 +46,7 @@ fn Child(non_reactive_prop: i32) -> Element {
}
"Sum: {computed}"
"{fut():?}"
}
}
-67
View File
@@ -1,67 +0,0 @@
/// 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 + 'static;
/// Returns the output of the dependency.
fn out(&self) -> Self::Out;
/// Returns true if the dependency has changed.
fn changed(&self, other: &Self::Out) -> bool {
self.out() != *other
}
}
impl Dependency for () {
type Out = ();
fn out(&self) -> Self::Out {}
}
/// A dependency is a trait that can be used to determine if a effect or selector should be re-run.
pub trait DependencyElement: 'static + PartialEq + Clone {}
impl<T> DependencyElement for T where T: 'static + PartialEq + Clone {}
impl<A: DependencyElement> Dependency for &A {
type Out = A;
fn out(&self) -> Self::Out {
(*self).clone()
}
}
macro_rules! impl_dep {
(
$($el:ident=$name:ident $other:ident,)*
) => {
impl< $($el),* > Dependency for ($(&$el,)*)
where
$(
$el: DependencyElement
),*
{
type Out = ($($el,)*);
fn out(&self) -> Self::Out {
let ($($name,)*) = self;
($((*$name).clone(),)*)
}
fn changed(&self, other: &Self::Out) -> bool {
let ($($name,)*) = self;
let ($($other,)*) = other;
$(
if *$name != $other {
return true;
}
)*
false
}
}
};
}
impl_dep!(A = a1 a2,);
impl_dep!(A = a1 a2, B = b1 b2,);
impl_dep!(A = a1 a2, B = b1 b2, C = c1 c2,);
impl_dep!(A = a1 a2, B = b1 b2, C = c1 c2, D = d1 d2,);
impl_dep!(A = a1 a2, B = b1 b2, C = c1 c2, D = d1 d2, E = e1 e2,);
impl_dep!(A = a1 a2, B = b1 b2, C = c1 c2, D = d1 d2, E = e1 e2, F = f1 f2,);
impl_dep!(A = a1 a2, B = b1 b2, C = c1 c2, D = d1 d2, E = e1 e2, F = f1 f2, G = g1 g2,);
impl_dep!(A = a1 a2, B = b1 b2, C = c1 c2, D = d1 d2, E = e1 e2, F = f1 f2, G = g1 g2, H = h1 h2,);
-3
View File
@@ -19,9 +19,6 @@ pub use map::*;
// mod comparer;
// pub use comparer::*;
mod dependency;
pub use dependency::*;
mod memo;
pub use memo::*;
+1 -35
View File
@@ -1,6 +1,6 @@
use crate::write::Writable;
use crate::{read::Readable, ReactiveContext, ReadableRef, Signal};
use crate::{CopyValue, Dependency, ReadOnlySignal};
use crate::{CopyValue, ReadOnlySignal};
use std::rc::Rc;
use std::{
cell::RefCell,
@@ -115,40 +115,6 @@ impl<T: 'static> Memo<T> {
pub fn id(&self) -> generational_box::GenerationalBoxId {
self.inner.id()
}
/// Adds an explicit dependency to the memo. If the dependency changes, the memo 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(count: u32) -> Element {
/// // Because the memo subscribes to `count` by adding it as a dependency, the memo will rerun every time `count` changes.
/// let new_count = use_memo(move || {
/// count + 1
/// })
/// .use_dependencies((&count,));
///
/// todo!()
/// }
/// ```
pub fn use_dependencies(self, dependency: impl Dependency) -> Self
where
T: PartialEq,
{
let mut dependencies_signal = use_hook(|| CopyValue::new(dependency.out()));
let changed = { dependency.changed(&*dependencies_signal.read()) };
if changed {
dependencies_signal.set(dependency.out());
self.recompute();
}
self
}
}
impl<T> Readable for Memo<T>