diff --git a/examples/fermi.rs b/examples/fermi.rs index f4391de5e..79e3da1d6 100644 --- a/examples/fermi.rs +++ b/examples/fermi.rs @@ -14,6 +14,7 @@ fn app(cx: Scope) -> Element { cx.render(rsx! { div { "hello {name}!" } Child {} + ChildWithRef{} }) } @@ -27,3 +28,28 @@ fn Child(cx: Scope) -> Element { } }) } + +static NAMES: AtomRef> = |_| vec!["world".to_string()]; + +fn ChildWithRef(cx: Scope) -> Element { + let names = use_atom_ref(&cx, NAMES); + + cx.render(rsx! { + div { + ul { + names.read().iter().map(|f| rsx!{ + li { "hello: {f}" } + }) + } + button { + onclick: move |_| { + let names = names.clone(); + cx.spawn(async move { + names.write().push("asd".to_string()); + }) + }, + "Add name" + } + } + }) +} diff --git a/packages/fermi/src/hooks/atom_ref.rs b/packages/fermi/src/hooks/atom_ref.rs index da9ad9367..fe488ee2f 100644 --- a/packages/fermi/src/hooks/atom_ref.rs +++ b/packages/fermi/src/hooks/atom_ref.rs @@ -16,15 +16,35 @@ use std::{ pub fn use_atom_ref(cx: &ScopeState, atom: AtomRef) -> &UseAtomRef { let root = use_atom_root(cx); - cx.use_hook(|_| { + &cx.use_hook(|_| { root.initialize(atom); - UseAtomRef { - ptr: atom.unique_id(), - root: root.clone(), - scope_id: cx.scope_id(), - value: root.register(atom, cx.scope_id()), - } + ( + UseAtomRef { + ptr: atom.unique_id(), + root: root.clone(), + scope_id: cx.scope_id(), + value: root.register(atom, cx.scope_id()), + }, + AtomRefSubscription { + ptr: atom.unique_id(), + root: root.clone(), + scope_id: cx.scope_id(), + }, + ) }) + .0 +} + +pub struct AtomRefSubscription { + ptr: AtomId, + root: Rc, + scope_id: ScopeId, +} + +impl Drop for AtomRefSubscription { + fn drop(&mut self) { + self.root.unsubscribe(self.ptr, self.scope_id) + } } pub struct UseAtomRef { @@ -34,6 +54,17 @@ pub struct UseAtomRef { scope_id: ScopeId, } +impl Clone for UseAtomRef { + fn clone(&self) -> Self { + Self { + ptr: self.ptr, + value: self.value.clone(), + root: self.root.clone(), + scope_id: self.scope_id, + } + } +} + impl UseAtomRef { pub fn read(&self) -> Ref { self.value.borrow() @@ -54,9 +85,3 @@ impl UseAtomRef { self.root.set(self.ptr, new); } } - -impl Drop for UseAtomRef { - fn drop(&mut self) { - self.root.unsubscribe(self.ptr, self.scope_id) - } -}