From 43b58bfba9cb0593ec25c96fbfa7ef7f832ce0a4 Mon Sep 17 00:00:00 2001 From: Greg Johnston Date: Tue, 19 Sep 2023 21:04:02 -0400 Subject: [PATCH 1/2] Revert "fix: #1742 part 2 (`Suspense` running children a second time => extra animations)" This reverts commit fafb6c01daaa638ac9aba606f4c6a0ee618fa4de. --- leptos/src/suspense_component.rs | 30 +++++++++++++++------------- leptos_reactive/src/lib.rs | 4 ++-- leptos_reactive/src/runtime.rs | 34 -------------------------------- 3 files changed, 18 insertions(+), 50 deletions(-) diff --git a/leptos/src/suspense_component.rs b/leptos/src/suspense_component.rs index ec18d46172..e4720dbe09 100644 --- a/leptos/src/suspense_component.rs +++ b/leptos/src/suspense_component.rs @@ -2,10 +2,8 @@ use leptos_dom::{DynChild, HydrationCtx, IntoView}; use leptos_macro::component; #[cfg(any(feature = "csr", feature = "hydrate"))] use leptos_reactive::SignalGet; -#[allow(unused)] use leptos_reactive::{ - create_memo, provide_context, run_as_child, SignalGetUntracked, - SuspenseContext, + create_memo, provide_context, SignalGetUntracked, SuspenseContext, }; #[cfg(not(any(feature = "csr", feature = "hydrate")))] use leptos_reactive::{with_owner, Owner, SharedContext}; @@ -77,6 +75,16 @@ where let owner = Owner::current().expect(" created with no reactive owner"); + // provide this SuspenseContext to any resources below it + // run in a memo so the children are children of this parent + let children = create_memo({ + let orig_children = Rc::clone(&orig_children); + move |_| { + provide_context(context); + orig_children().into_view() + } + }); + // likewise for the fallback let fallback = create_memo({ move |_| { @@ -92,20 +100,13 @@ where let child = DynChild::new({ move || { - // provide this SuspenseContext to any resources below it - // run in a memo so the children are children of this parent - let children = run_as_child({ - let orig_children = Rc::clone(&orig_children); - move || { - provide_context(context); - orig_children().into_view() - } - }); + // pull lazy memo before checking if context is ready + let children_rendered = children.get_untracked(); #[cfg(any(feature = "csr", feature = "hydrate"))] { if ready.get() { - children + children_rendered } else { fallback.get_untracked() } @@ -122,7 +123,8 @@ where if context.pending_resources.get() == 0 { with_owner(owner, move || { //HydrationCtx::continue_from(current_id); - DynChild::new(move || children.clone()).into_view() + DynChild::new(move || children_rendered.clone()) + .into_view() }) } // show the fallback, but also prepare to stream HTML diff --git a/leptos_reactive/src/lib.rs b/leptos_reactive/src/lib.rs index a7dc6bbf3b..7367ab737c 100644 --- a/leptos_reactive/src/lib.rs +++ b/leptos_reactive/src/lib.rs @@ -114,8 +114,8 @@ pub use resource::*; use runtime::*; pub use runtime::{ as_child_of_current_owner, batch, create_runtime, current_runtime, - on_cleanup, run_as_child, set_current_runtime, untrack, - untrack_with_diagnostics, with_current_owner, with_owner, Owner, RuntimeId, + on_cleanup, set_current_runtime, untrack, untrack_with_diagnostics, + with_current_owner, with_owner, Owner, RuntimeId, }; pub use selector::*; pub use serialization::*; diff --git a/leptos_reactive/src/runtime.rs b/leptos_reactive/src/runtime.rs index 6edee94883..fcb5f4eab6 100644 --- a/leptos_reactive/src/runtime.rs +++ b/leptos_reactive/src/runtime.rs @@ -680,40 +680,6 @@ where } } -/// Runs the given function as a child of the current Owner, once. -pub fn run_as_child(f: impl FnOnce() -> T + 'static) -> T { - let owner = with_runtime(|runtime| runtime.owner.get()) - .expect("runtime should be alive when created"); - let (value, disposer) = with_runtime(|runtime| { - let prev_observer = runtime.observer.take(); - let prev_owner = runtime.owner.take(); - - runtime.owner.set(owner); - runtime.observer.set(owner); - - let id = runtime.nodes.borrow_mut().insert(ReactiveNode { - value: None, - state: ReactiveNodeState::Clean, - node_type: ReactiveNodeType::Trigger, - }); - runtime.push_scope_property(ScopeProperty::Trigger(id)); - let disposer = Disposer(id); - - runtime.owner.set(Some(id)); - runtime.observer.set(Some(id)); - - let v = f(); - - runtime.observer.set(prev_observer); - runtime.owner.set(prev_owner); - - (v, disposer) - }) - .expect("runtime should be alive when run"); - on_cleanup(move || drop(disposer)); - value -} - /// Wraps the given function so that, whenever it is called, it is run /// in the reactive scope of whatever the reactive owner was when it was /// created. From f85bfd31db8a7579c1a1e137ec8f52a74f9ea1cc Mon Sep 17 00:00:00 2001 From: Greg Johnston Date: Tue, 19 Sep 2023 21:04:41 -0400 Subject: [PATCH 2/2] fix: `Transition` double-rendering --- leptos/src/transition.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/leptos/src/transition.rs b/leptos/src/transition.rs index 0dd89f4946..a2ea85b5e6 100644 --- a/leptos/src/transition.rs +++ b/leptos/src/transition.rs @@ -2,7 +2,7 @@ use leptos_dom::{Fragment, HydrationCtx, IntoView, View}; use leptos_macro::component; use leptos_reactive::{ create_isomorphic_effect, create_rw_signal, use_context, RwSignal, - SignalGet, SignalSet, SignalSetter, SuspenseContext, + SignalGet, SignalGetUntracked, SignalSet, SignalSetter, SuspenseContext, }; use std::{ cell::{Cell, RefCell}, @@ -125,7 +125,7 @@ where let suspense_context = held_suspense_context.borrow().unwrap(); if cfg!(feature = "hydrate") - || !first_run.get() + || !first_run.get_untracked() || (cfg!(feature = "csr") && first_run.get()) { *prev_children.borrow_mut() = Some(frag.clone()); @@ -161,7 +161,7 @@ fn is_first_run( false } else { match ( - first_run.get(), + first_run.get_untracked(), cfg!(feature = "hydrate"), suspense_context.has_local_only(), ) {