Merge pull request #1386 from ealmloff/fix-new-signals-in-effects
Fix leaked signals created in effects
This commit is contained in:
3 files changed
+21
-10
No files matched your search
@@ -18,7 +18,8 @@ pub(crate) fn get_effect_stack() -> EffectStack {
|
|||||||
Some(rt) => rt,
|
Some(rt) => rt,
|
||||||
None => {
|
None => {
|
||||||
let store = EffectStack::default();
|
let store = EffectStack::default();
|
||||||
provide_root_context(store).expect("in a virtual dom")
|
provide_root_context(store.clone());
|
||||||
|
store
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -54,6 +55,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 +75,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)),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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")
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user