diff --git a/packages/hooks/src/use_shared_state.rs b/packages/hooks/src/use_shared_state.rs index b900b9dc6c..18ce1e5f1f 100644 --- a/packages/hooks/src/use_shared_state.rs +++ b/packages/hooks/src/use_shared_state.rs @@ -81,10 +81,12 @@ pub(crate) struct ProvidedStateInner { value: T, notify_any: Arc, consumers: HashSet, + gen: usize, } impl ProvidedStateInner { pub(crate) fn notify_consumers(&mut self) { + self.gen += 1; for consumer in self.consumers.iter() { (self.notify_any)(*consumer); } @@ -157,7 +159,7 @@ impl ProvidedStateInner { /// /// Right now, there is not a distinction between read-only and write-only, so every consumer will be notified. pub fn use_shared_state(cx: &ScopeState) -> Option<&UseSharedState> { - let state: &Option> = &*cx.use_hook(move || { + let state_owner: &mut Option> = &mut *cx.use_hook(move || { let scope_id = cx.scope_id(); let root = cx.consume_context::>()?; @@ -167,7 +169,10 @@ pub fn use_shared_state(cx: &ScopeState) -> Option<&UseSharedState Drop for UseSharedStateOwner { /// State that is shared between components through the context system pub struct UseSharedState { pub(crate) inner: Rc>>, + gen: usize, } impl UseSharedState { fn new(inner: Rc>>) -> Self { - Self { inner } + let gen = inner.borrow().gen; + Self { inner, gen } } /// Notify all consumers of the state that it has changed. (This is called automatically when you call "write") @@ -302,15 +309,14 @@ impl Clone for UseSharedState { fn clone(&self) -> Self { Self { inner: self.inner.clone(), + gen: self.gen, } } } -impl PartialEq for UseSharedState { +impl PartialEq for UseSharedState { fn eq(&self, other: &Self) -> bool { - let first = self.inner.borrow(); - let second = other.inner.borrow(); - first.value == second.value + self.gen == other.gen } } @@ -360,6 +366,7 @@ pub fn use_shared_state_provider(cx: &ScopeState, f: impl FnOnce() - value: f(), notify_any: cx.schedule_update_any(), consumers: HashSet::new(), + gen: 0, })); cx.provide_context(state);