mirror of
https://github.com/DioxusLabs/dioxus
synced 2024-11-30 08:00:21 +00:00
don't subscribe in tasks or event handlers
This commit is contained in:
parent
4447709ac8
commit
0c17bdb737
6 changed files with 35 additions and 16 deletions
|
@ -73,10 +73,11 @@ pub(crate) mod innerlude {
|
|||
}
|
||||
|
||||
pub use crate::innerlude::{
|
||||
fc_to_builder, AnyValue, Attribute, AttributeValue, BorrowedAttributeValue, CapturedError,
|
||||
Component, DynamicNode, Element, ElementId, Event, Fragment, IntoDynNode, LazyNodes, Mutation,
|
||||
Mutations, Properties, RenderReturn, Scope, ScopeId, ScopeState, Scoped, TaskId, Template,
|
||||
TemplateAttribute, TemplateNode, VComponent, VNode, VPlaceholder, VText, VirtualDom,
|
||||
fc_to_builder, vdom_is_rendering, AnyValue, Attribute, AttributeValue, BorrowedAttributeValue,
|
||||
CapturedError, Component, DynamicNode, Element, ElementId, Event, Fragment, IntoDynNode,
|
||||
LazyNodes, Mutation, Mutations, Properties, RenderReturn, Scope, ScopeId, ScopeState, Scoped,
|
||||
TaskId, Template, TemplateAttribute, TemplateNode, VComponent, VNode, VPlaceholder, VText,
|
||||
VirtualDom,
|
||||
};
|
||||
|
||||
/// The purpose of this module is to alleviate imports of many common types
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use std::cell::{Ref, RefCell};
|
||||
use std::cell::{Cell, Ref, RefCell};
|
||||
|
||||
use crate::{innerlude::Scheduler, scope_context::ScopeContext, scopes::ScopeId};
|
||||
use std::rc::Rc;
|
||||
|
@ -47,6 +47,7 @@ pub struct Runtime {
|
|||
|
||||
// We use this to track the current scope
|
||||
pub(crate) scope_stack: RefCell<Vec<ScopeId>>,
|
||||
pub(crate) rendering: Cell<bool>,
|
||||
}
|
||||
|
||||
impl Runtime {
|
||||
|
@ -57,6 +58,8 @@ impl Runtime {
|
|||
scope_contexts: Default::default(),
|
||||
|
||||
scope_stack: Default::default(),
|
||||
|
||||
rendering: Cell::new(true),
|
||||
});
|
||||
runtime
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ impl VirtualDom {
|
|||
|
||||
// update the scope stack
|
||||
self.runtime.scope_stack.borrow_mut().push(task.scope);
|
||||
self.runtime.rendering.set(false);
|
||||
|
||||
// If the task completes...
|
||||
if task.task.borrow_mut().as_mut().poll(&mut cx).is_ready() {
|
||||
|
@ -33,5 +34,6 @@ impl VirtualDom {
|
|||
|
||||
// Remove the scope from the stack
|
||||
self.runtime.scope_stack.borrow_mut().pop();
|
||||
self.runtime.rendering.set(true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -263,6 +263,12 @@ pub fn current_scope_id() -> Option<ScopeId> {
|
|||
with_runtime(|rt| rt.current_scope_id()).flatten()
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
/// Check if the virtual dom is currently inside of the body of a component
|
||||
pub fn vdom_is_rendering() -> bool {
|
||||
with_runtime(|rt| rt.rendering.get()).unwrap_or_default()
|
||||
}
|
||||
|
||||
/// Consume context from the current scope
|
||||
pub fn consume_context<T: 'static + Clone>() -> Option<T> {
|
||||
with_current_scope(|cx| cx.consume_context::<T>()).flatten()
|
||||
|
|
|
@ -392,10 +392,12 @@ impl VirtualDom {
|
|||
if let AttributeValue::Listener(listener) = listener {
|
||||
let origin = el_ref.scope;
|
||||
self.runtime.scope_stack.borrow_mut().push(origin);
|
||||
self.runtime.rendering.set(false);
|
||||
if let Some(cb) = listener.borrow_mut().as_deref_mut() {
|
||||
cb(uievent.clone());
|
||||
}
|
||||
self.runtime.scope_stack.borrow_mut().pop();
|
||||
self.runtime.rendering.set(true);
|
||||
|
||||
if !uievent.propagates.get() {
|
||||
return;
|
||||
|
@ -426,10 +428,12 @@ impl VirtualDom {
|
|||
if let AttributeValue::Listener(listener) = &attr.value {
|
||||
let origin = el_ref.scope;
|
||||
self.runtime.scope_stack.borrow_mut().push(origin);
|
||||
self.runtime.rendering.set(false);
|
||||
if let Some(cb) = listener.borrow_mut().as_deref_mut() {
|
||||
cb(uievent.clone());
|
||||
}
|
||||
self.runtime.scope_stack.borrow_mut().pop();
|
||||
self.runtime.rendering.set(true);
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -109,6 +109,8 @@ impl<T: 'static> Signal<T> {
|
|||
effect_subscribers.push(effect);
|
||||
}
|
||||
} else if let Some(current_scope_id) = current_scope_id() {
|
||||
// only subscribe if the vdom is rendering
|
||||
if dioxus_core::vdom_is_rendering() {
|
||||
log::trace!(
|
||||
"{:?} subscribed to {:?}",
|
||||
self.inner.value,
|
||||
|
@ -122,6 +124,7 @@ impl<T: 'static> Signal<T> {
|
|||
inner.subscribers.borrow_mut().push(unsubscriber.scope);
|
||||
}
|
||||
}
|
||||
}
|
||||
Ref::map(inner, |v| &v.value)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue