From cbddda001b30dcd814a6431f9b246d19d225ad7b Mon Sep 17 00:00:00 2001 From: Greg Johnston Date: Thu, 12 Dec 2024 18:55:39 -0500 Subject: [PATCH] fix: only mark a memo Check if it isn't already Dirty (closes #3339) --- reactive_graph/src/computed/inner.rs | 4 ++- reactive_graph/tests/memo.rs | 37 ++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/reactive_graph/src/computed/inner.rs b/reactive_graph/src/computed/inner.rs index 6512a960a6..4f6bb3c5a0 100644 --- a/reactive_graph/src/computed/inner.rs +++ b/reactive_graph/src/computed/inner.rs @@ -67,7 +67,9 @@ where fn mark_check(&self) { { let mut lock = self.write().or_poisoned(); - lock.state = ReactiveNodeState::Check; + if lock.state != ReactiveNodeState::Dirty { + lock.state = ReactiveNodeState::Check; + } } for sub in (&self.read().or_poisoned().subscribers).into_iter() { sub.mark_check(); diff --git a/reactive_graph/tests/memo.rs b/reactive_graph/tests/memo.rs index 2e6d3ae9aa..ec531e96b9 100644 --- a/reactive_graph/tests/memo.rs +++ b/reactive_graph/tests/memo.rs @@ -443,3 +443,40 @@ fn unsync_derived_signal_and_memo() { assert_eq!(f.with(|n| *n), 6); assert_eq!(f.get_untracked(), 6); } + +#[test] +fn memo_updates_even_if_not_read_until_later() { + #![allow(clippy::bool_assert_comparison)] + + // regression test for https://github.com/leptos-rs/leptos/issues/3339 + + let input = RwSignal::new(0); + let first_memo = Memo::new(move |_| input.get() == 1); + let second_memo = Memo::new(move |_| first_memo.get()); + + assert_eq!(input.get(), 0); + assert_eq!(first_memo.get(), false); + + println!("update to 1"); + input.set(1); + assert_eq!(input.get(), 1); + println!("read memo 1"); + assert_eq!(first_memo.get(), true); + println!("read memo 2"); + assert_eq!(second_memo.get(), true); + + // this time, we don't read the memo + println!("\nupdate to 2"); + input.set(2); + assert_eq!(input.get(), 2); + println!("read memo 1"); + assert_eq!(first_memo.get(), false); + + println!("\nupdate to 3"); + input.set(3); + assert_eq!(input.get(), 3); + println!("read memo 1"); + assert_eq!(first_memo.get(), false); + println!("read memo 2"); + assert_eq!(second_memo.get(), false); +}