mirror of
https://github.com/leptos-rs/leptos
synced 2024-11-10 06:44:17 +00:00
fix: memoize Suspense readiness to avoid rerendering children/fallback (#1642)
This commit is contained in:
parent
4a43983f4e
commit
2ca24883ac
5 changed files with 19 additions and 14 deletions
|
@ -1,5 +1,7 @@
|
|||
use leptos_dom::{DynChild, HydrationCtx, IntoView};
|
||||
use leptos_macro::component;
|
||||
#[cfg(any(feature = "csr", feature = "hydrate"))]
|
||||
use leptos_reactive::SignalGet;
|
||||
use leptos_reactive::{
|
||||
create_memo, provide_context, SignalGetUntracked, SuspenseContext,
|
||||
};
|
||||
|
@ -93,6 +95,9 @@ where
|
|||
|
||||
let current_id = HydrationCtx::next_component();
|
||||
|
||||
#[cfg(any(feature = "csr", feature = "hydrate"))]
|
||||
let ready = context.ready();
|
||||
|
||||
let child = DynChild::new({
|
||||
move || {
|
||||
// pull lazy memo before checking if context is ready
|
||||
|
@ -100,7 +105,7 @@ where
|
|||
|
||||
#[cfg(any(feature = "csr", feature = "hydrate"))]
|
||||
{
|
||||
if context.ready() {
|
||||
if ready.get() {
|
||||
children_rendered
|
||||
} else {
|
||||
fallback.get_untracked()
|
||||
|
|
|
@ -99,7 +99,9 @@ where
|
|||
cfg!(feature = "csr") && first_run.get();
|
||||
let is_first_run =
|
||||
is_first_run(first_run, &suspense_context);
|
||||
first_run.set(false);
|
||||
if was_first_run {
|
||||
first_run.set(false)
|
||||
}
|
||||
|
||||
if let Some(prev_children) = &*prev_child.borrow() {
|
||||
if is_first_run || was_first_run {
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
//! Types that handle asynchronous data loading via `<Suspense/>`.
|
||||
|
||||
use crate::{
|
||||
create_isomorphic_effect, create_rw_signal, create_signal, oco::Oco,
|
||||
queue_microtask, signal::SignalGet, store_value, ReadSignal, RwSignal,
|
||||
SignalSet, SignalUpdate, StoredValue, WriteSignal,
|
||||
create_isomorphic_effect, create_memo, create_rw_signal, create_signal,
|
||||
oco::Oco, queue_microtask, signal::SignalGet, store_value, Memo,
|
||||
ReadSignal, RwSignal, SignalSet, SignalUpdate, StoredValue, WriteSignal,
|
||||
};
|
||||
use futures::Future;
|
||||
use std::{cell::RefCell, collections::VecDeque, pin::Pin, rc::Rc};
|
||||
|
@ -154,10 +154,9 @@ impl SuspenseContext {
|
|||
}
|
||||
|
||||
/// Tests whether all of the pending resources have resolved.
|
||||
pub fn ready(&self) -> bool {
|
||||
self.pending_resources
|
||||
.try_with(|n| *n == 0)
|
||||
.unwrap_or(false)
|
||||
pub fn ready(&self) -> Memo<bool> {
|
||||
let pending = self.pending_resources;
|
||||
create_memo(move |_| pending.try_with(|n| *n == 0).unwrap_or(false))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ pub fn Outlet() -> impl IntoView {
|
|||
move |prev| {
|
||||
let outlet = outlet.get();
|
||||
let is_fallback =
|
||||
!global_suspense.with_inner(SuspenseContext::ready);
|
||||
!global_suspense.with_inner(|c| c.ready().get());
|
||||
if prev.is_none() {
|
||||
set_current_view.set(outlet);
|
||||
} else if !is_fallback {
|
||||
|
@ -81,7 +81,7 @@ pub fn Outlet() -> impl IntoView {
|
|||
move || {
|
||||
let is_fallback = untrack(move || {
|
||||
!global_suspense
|
||||
.with_inner(SuspenseContext::ready)
|
||||
.with_inner(|c| c.ready().get())
|
||||
});
|
||||
if !is_fallback {
|
||||
set_current_view.set(outlet);
|
||||
|
|
|
@ -451,8 +451,7 @@ fn root_route(
|
|||
|
||||
create_effect(move |prev| {
|
||||
let root = root_view.get();
|
||||
let is_fallback =
|
||||
!global_suspense.with_inner(SuspenseContext::ready);
|
||||
let is_fallback = !global_suspense.with_inner(|c| c.ready().get());
|
||||
if prev.is_none() {
|
||||
set_current_view.set(root);
|
||||
} else if !is_fallback {
|
||||
|
@ -460,7 +459,7 @@ fn root_route(
|
|||
let global_suspense = global_suspense.clone();
|
||||
move || {
|
||||
let is_fallback = untrack(move || {
|
||||
!global_suspense.with_inner(SuspenseContext::ready)
|
||||
!global_suspense.with_inner(|c| c.ready().get())
|
||||
});
|
||||
if !is_fallback {
|
||||
set_current_view.set(root);
|
||||
|
|
Loading…
Reference in a new issue