Fix creating signals in effects

This commit is contained in:
Evan Almloff committed 2023-08-21 14:42:56 -05:00
1 parent d8704a0447
commit 38274da3ee
3 files changed
+19 -9

No files matched your search

+2
View File
@@ -54,6 +54,7 @@ pub fn use_effect_with_dependencies<D: Dependency>(
/// Effects allow you to run code when a signal changes. Effects are run immediately and whenever any signal it reads changes. /// Effects allow you to run code when a signal changes. Effects are run immediately and whenever any signal it reads changes.
#[derive(Copy, Clone, PartialEq)] #[derive(Copy, Clone, PartialEq)]
pub struct Effect { pub struct Effect {
pub(crate) source: ScopeId,
pub(crate) callback: CopyValue<Box<dyn FnMut()>>, pub(crate) callback: CopyValue<Box<dyn FnMut()>>,
} }
@@ -73,6 +74,7 @@ impl Effect {
/// The signal will be owned by the current component and will be dropped when the component is dropped. /// The signal will be owned by the current component and will be dropped when the component is dropped.
pub fn new(callback: impl FnMut() + 'static) -> Self { pub fn new(callback: impl FnMut() + 'static) -> Self {
let myself = Self { let myself = Self {
source: current_scope_id().expect("in a virtual dom"),
callback: CopyValue::new(Box::new(callback)), callback: CopyValue::new(Box::new(callback)),
}; };
+16 -9
View File
@@ -2,14 +2,13 @@ use std::cell::{Ref, RefMut};
use std::rc::Rc; use std::rc::Rc;
use dioxus_core::prelude::{ use dioxus_core::prelude::*;
consume_context, consume_context_from_scope, current_scope_id, provide_context,
provide_context_to_scope, provide_root_context,
};
use dioxus_core::ScopeId; use dioxus_core::ScopeId;
use generational_box::{GenerationalBox, Owner, Store}; use generational_box::{GenerationalBox, Owner, Store};
use crate::Effect;
fn current_store() -> Store { fn current_store() -> Store {
match consume_context() { match consume_context() {
Some(rt) => rt, Some(rt) => rt,
@@ -21,12 +20,20 @@ fn current_store() -> Store {
} }
fn current_owner() -> Rc<Owner> { fn current_owner() -> Rc<Owner> {
match consume_context() { match Effect::current() {
Some(rt) => rt, // If we are inside of an effect, we should use the owner of the effect as the owner of the value.
None => { Some(effect) => {
let owner = Rc::new(current_store().owner()); let scope_id = effect.source;
provide_context(owner).expect("in a virtual dom") owner_in_scope(scope_id)
} }
// Otherwise either get an owner from the current scope or create a new one.
None => match has_context() {
Some(rt) => rt,
None => {
let owner = Rc::new(current_store().owner());
provide_context(owner).expect("in a virtual dom")
}
},
} }
} }
+1
View File
@@ -74,6 +74,7 @@ pub fn selector<R: PartialEq>(mut f: impl FnMut() -> R + 'static) -> ReadOnlySig
inner: CopyValue::invalid(), inner: CopyValue::invalid(),
}; };
let effect = Effect { let effect = Effect {
source: current_scope_id().expect("in a virtual dom"),
callback: CopyValue::invalid(), callback: CopyValue::invalid(),
}; };