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.
#[derive(Copy, Clone, PartialEq)]
pub struct Effect {
pub(crate) source: ScopeId,
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.
pub fn new(callback: impl FnMut() + 'static) -> Self {
let myself = Self {
source: current_scope_id().expect("in a virtual dom"),
callback: CopyValue::new(Box::new(callback)),
};
+16 -9
View File
@@ -2,14 +2,13 @@ use std::cell::{Ref, RefMut};
use std::rc::Rc;
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::prelude::*;
use dioxus_core::ScopeId;
use generational_box::{GenerationalBox, Owner, Store};
use crate::Effect;
fn current_store() -> Store {
match consume_context() {
Some(rt) => rt,
@@ -21,12 +20,20 @@ fn current_store() -> Store {
}
fn current_owner() -> Rc<Owner> {
match consume_context() {
Some(rt) => rt,
None => {
let owner = Rc::new(current_store().owner());
provide_context(owner).expect("in a virtual dom")
match Effect::current() {
// If we are inside of an effect, we should use the owner of the effect as the owner of the value.
Some(effect) => {
let scope_id = effect.source;
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(),
};
let effect = Effect {
source: current_scope_id().expect("in a virtual dom"),
callback: CopyValue::invalid(),
};