1
0
Evan Almloff 1 жил өмнө
parent
commit
b3c5158524

+ 2 - 2
packages/signals/README.md

@@ -106,7 +106,7 @@ use dioxus_signals::*;
 #[component]
 fn App(cx: Scope) -> Element {
     let signal = use_signal(cx, || 0);
-    let doubled = use_selector(cx, || signal * 2);
+    let doubled = use_selector(cx, move || signal * 2);
 
     render! {
         button {
@@ -114,7 +114,7 @@ fn App(cx: Scope) -> Element {
             "Increase"
         }
         Child {
-            signal: signal
+            signal: doubled
         }
     }
 }

+ 26 - 0
packages/signals/examples/send.rs

@@ -0,0 +1,26 @@
+use dioxus::prelude::*;
+use dioxus_signals::*;
+
+fn main() {
+    tracing_subscriber::fmt::init();
+    dioxus_desktop::launch(App);
+}
+
+#[component]
+fn App(cx: Scope) -> Element {
+    let mut signal = use_signal_sync(cx, || 0);
+    cx.use_hook(|| {
+        std::thread::spawn(move || loop {
+            std::thread::sleep(std::time::Duration::from_secs(1));
+            signal += 1;
+        })
+    });
+
+    render! {
+        button {
+            onclick: move |_| signal += 1,
+            "Increase"
+        }
+        "{signal}"
+    }
+}

+ 6 - 0
packages/signals/src/impls.rs

@@ -36,6 +36,12 @@ macro_rules! read_impls {
                 self.with(|v| Debug::fmt(v, f))
             }
         }
+
+        impl<T: PartialEq + 'static, S: $bound> PartialEq<T> for $ty<T, S> {
+            fn eq(&self, other: &T) -> bool {
+                self.with(|v| *v == *other)
+            }
+        }
     };
 }
 

+ 1 - 0
packages/signals/src/lib.rs

@@ -15,3 +15,4 @@ pub(crate) mod signal;
 pub use signal::*;
 mod dependency;
 pub use dependency::*;
+pub use generational_box::{Storage, SyncStorage, UnsyncStorage};

+ 7 - 5
packages/signals/src/signal.rs

@@ -11,7 +11,9 @@ use dioxus_core::{
     prelude::{current_scope_id, has_context, provide_context, schedule_update_any},
     ScopeId, ScopeState,
 };
-use generational_box::{GenerationalBoxId, Mappable, MappableMut, Storage, UnsyncStorage};
+use generational_box::{
+    GenerationalBoxId, Mappable, MappableMut, Storage, SyncStorage, UnsyncStorage,
+};
 use parking_lot::RwLock;
 
 use crate::{get_effect_ref, CopyValue, EffectStackRef, EFFECT_STACK};
@@ -59,7 +61,7 @@ pub fn use_signal<T: 'static>(cx: &ScopeState, f: impl FnOnce() -> T) -> Signal<
 /// use dioxus_signals::*;
 ///
 /// fn App(cx: Scope) -> Element {
-///     let mut count = use_signal(cx, || 0);
+///     let mut count = use_signal_sync(cx, || 0);
 ///
 ///     // Because signals have automatic dependency tracking, if you never read them in a component, that component will not be re-rended when the signal is updated.
 ///     // The app component will never be rerendered in this example.
@@ -67,7 +69,7 @@ pub fn use_signal<T: 'static>(cx: &ScopeState, f: impl FnOnce() -> T) -> Signal<
 /// }
 ///
 /// #[component]
-/// fn Child(cx: Scope, state: Signal<u32>) -> Element {
+/// fn Child(cx: Scope, state: Signal<u32, SyncStorage>) -> Element {
 ///     let state = *state;
 ///
 ///     use_future!(cx,  |()| async move {
@@ -90,8 +92,8 @@ pub fn use_signal<T: 'static>(cx: &ScopeState, f: impl FnOnce() -> T) -> Signal<
 pub fn use_signal_sync<T: Send + Sync + 'static>(
     cx: &ScopeState,
     f: impl FnOnce() -> T,
-) -> Signal<T, UnsyncStorage> {
-    *cx.use_hook(|| Signal::new(f()))
+) -> Signal<T, SyncStorage> {
+    *cx.use_hook(|| Signal::new_maybe_sync(f()))
 }
 
 #[derive(Clone)]

+ 15 - 5
packages/signals/tests/selector.rs

@@ -24,7 +24,7 @@ fn memos_rerun() {
             counter.borrow_mut().component += 1;
 
             let mut signal = use_signal(cx, || 0);
-            let memo = cx.use_hook(move || {
+            let memo = *cx.use_hook(move || {
                 to_owned![counter];
                 selector(move || {
                     counter.borrow_mut().effect += 1;
@@ -32,9 +32,17 @@ fn memos_rerun() {
                     signal.value()
                 })
             });
-            assert_eq!(memo.value(), 0);
+            let generation = use_signal(cx, || cx.generation());
+            generation.set(cx.generation());
+            dioxus_signals::use_effect(cx, move || {
+                if generation == 1 {
+                    assert_eq!(memo.value(), 0);
+                }
+                if generation == 3 {
+                    assert_eq!(memo.value(), 1);
+                }
+            });
             signal += 1;
-            assert_eq!(memo.value(), 1);
 
             render! {
                 div {}
@@ -44,14 +52,15 @@ fn memos_rerun() {
     );
 
     let _ = dom.rebuild().santize();
+    let _ = dom.render_immediate();
 
     let current_counter = counter.borrow();
     assert_eq!(current_counter.component, 1);
     assert_eq!(current_counter.effect, 2);
 }
 
-#[test]
-fn memos_prevents_component_rerun() {
+#[tokio::test]
+async fn memos_prevents_component_rerun() {
     let _ = simple_logger::SimpleLogger::new().init();
 
     #[derive(Default)]
@@ -126,6 +135,7 @@ fn memos_prevents_component_rerun() {
     let _ = dom.rebuild().santize();
     dom.mark_dirty(ScopeId::ROOT);
     dom.render_immediate();
+    dom.render_immediate();
 
     {
         let current_counter = counter.borrow();