mirror of
https://github.com/leptos-rs/leptos
synced 2024-11-10 14:54:16 +00:00
Final Suspense
fix?
This commit is contained in:
parent
6354b79588
commit
590ec40e0c
5 changed files with 33 additions and 23 deletions
|
@ -1,8 +1,10 @@
|
|||
use cfg_if::cfg_if;
|
||||
use leptos_macro::component;
|
||||
use std::rc::Rc;
|
||||
use leptos_dom::{DynChild, Fragment, HydrationCtx, IntoView, Component};
|
||||
use leptos_dom::{DynChild, Fragment, IntoView, Component};
|
||||
use leptos_reactive::{provide_context, Scope, SuspenseContext};
|
||||
#[cfg(not(any(feature = "csr", feature = "hydrate")))]
|
||||
use leptos_dom::{HydrationCtx, HydrationKey};
|
||||
|
||||
/// If any [Resources](leptos_reactive::Resource) are read in the `children` of this
|
||||
/// component, it will show the `fallback` while they are loading. Once all are resolved,
|
||||
|
@ -71,16 +73,15 @@ where
|
|||
let orig_child = Rc::new(children);
|
||||
|
||||
Component::new("Suspense", move |cx| {
|
||||
DynChild::new(move || {
|
||||
let current_id = HydrationCtx::peek();
|
||||
#[cfg(not(any(feature = "csr", feature = "hydrate")))]
|
||||
let current_id = HydrationCtx::peek();
|
||||
|
||||
DynChild::new(move || {
|
||||
cfg_if! {
|
||||
if #[cfg(any(feature = "csr", feature = "hydrate"))] {
|
||||
if context.ready() {
|
||||
HydrationCtx::continue_from(current_id);
|
||||
orig_child(cx).into_view(cx)
|
||||
} else {
|
||||
HydrationCtx::continue_from(current_id);
|
||||
fallback().into_view(cx)
|
||||
}
|
||||
} else {
|
||||
|
@ -95,10 +96,15 @@ where
|
|||
// show the fallback, but also prepare to stream HTML
|
||||
else {
|
||||
let orig_child = Rc::clone(&orig_child);
|
||||
|
||||
cx.register_suspense(context, ¤t_id.to_string(), {
|
||||
let current_id = current_id.clone();
|
||||
let fragment_id = HydrationKey {
|
||||
previous: current_id.previous,
|
||||
offset: current_id.offset + 1
|
||||
};
|
||||
move || {
|
||||
HydrationCtx::continue_from(current_id);
|
||||
HydrationCtx::continue_from(fragment_id);
|
||||
orig_child(cx)
|
||||
.into_view(cx)
|
||||
.render_to_string(cx)
|
||||
|
@ -111,7 +117,7 @@ where
|
|||
}
|
||||
};
|
||||
|
||||
HydrationCtx::continue_from(current_id);
|
||||
HydrationCtx::continue_from(current_id.clone());
|
||||
|
||||
initial
|
||||
}
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
use cfg_if::cfg_if;
|
||||
use leptos_dom::{Component, DynChild, Fragment, IntoView, HydrationCtx};
|
||||
use leptos_dom::{Component, DynChild, Fragment, IntoView};
|
||||
use leptos_macro::component;
|
||||
use leptos_reactive::{provide_context, Scope, SignalSetter, SuspenseContext};
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
#[cfg(not(any(feature = "csr", feature = "hydrate")))]
|
||||
use leptos_dom::{HydrationCtx, HydrationKey};
|
||||
|
||||
/// If any [Resource](leptos_reactive::Resource)s are read in the `children` of this
|
||||
/// component, it will show the `fallback` while they are loading. Once all are resolved,
|
||||
|
@ -84,14 +86,13 @@ where
|
|||
let prev_child = RefCell::new(None);
|
||||
|
||||
Component::new("Transition", move |cx| {
|
||||
DynChild::new(move || {
|
||||
let current_id = HydrationCtx::peek();
|
||||
|
||||
#[cfg(not(any(feature = "csr", feature = "hydrate")))]
|
||||
let current_id = HydrationCtx::peek();
|
||||
|
||||
DynChild::new(move || {
|
||||
cfg_if! {
|
||||
if #[cfg(any(feature = "csr", feature = "hydrate"))] {
|
||||
if context.ready() {
|
||||
leptos_dom::log!("showing reading view");
|
||||
HydrationCtx::continue_from(current_id);
|
||||
let current_child = orig_child(cx).into_view(cx);
|
||||
*prev_child.borrow_mut() = Some(current_child.clone());
|
||||
if let Some(pending) = &set_pending {
|
||||
|
@ -99,14 +100,11 @@ where
|
|||
}
|
||||
current_child
|
||||
} else if let Some(prev_child) = &*prev_child.borrow() {
|
||||
leptos_dom::log!("holding current view {prev_child:?}");
|
||||
if let Some(pending) = &set_pending {
|
||||
pending.set(true);
|
||||
}
|
||||
prev_child.clone()
|
||||
} else {
|
||||
HydrationCtx::continue_from(current_id);
|
||||
leptos_dom::log!("showing fallback view");
|
||||
if let Some(pending) = &set_pending {
|
||||
pending.set(true);
|
||||
}
|
||||
|
@ -128,8 +126,12 @@ where
|
|||
let orig_child = Rc::clone(&orig_child);
|
||||
cx.register_suspense(context, ¤t_id.to_string(), {
|
||||
let current_id = current_id.clone();
|
||||
let fragment_id = HydrationKey {
|
||||
previous: current_id.previous,
|
||||
offset: current_id.offset + 1
|
||||
};
|
||||
move || {
|
||||
HydrationCtx::continue_from(current_id);
|
||||
HydrationCtx::continue_from(fragment_id);
|
||||
orig_child(cx)
|
||||
.into_view(cx)
|
||||
.render_to_string(cx)
|
||||
|
@ -142,7 +144,7 @@ where
|
|||
}
|
||||
};
|
||||
|
||||
HydrationCtx::continue_from(current_id);
|
||||
HydrationCtx::continue_from(current_id.clone());
|
||||
|
||||
initial
|
||||
}
|
||||
|
|
|
@ -18,9 +18,12 @@ static mut IS_HYDRATING: LazyCell<bool> = LazyCell::new(|| {
|
|||
return crate::document().get_element_by_id("_0-0-0").is_some();
|
||||
});
|
||||
|
||||
/// A stable identifer within the server-rendering or hydration process.
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct HydrationKey {
|
||||
/// The key of the previous component.
|
||||
pub previous: String,
|
||||
/// The element offset within the current component.
|
||||
pub offset: usize
|
||||
}
|
||||
|
||||
|
|
|
@ -24,8 +24,7 @@ pub use components::*;
|
|||
pub use events::typed as ev;
|
||||
pub use helpers::*;
|
||||
pub use html::*;
|
||||
pub use hydration::HydrationCtx;
|
||||
use hydration::HydrationKey;
|
||||
pub use hydration::{HydrationCtx, HydrationKey};
|
||||
pub use js_sys;
|
||||
use leptos_reactive::Scope;
|
||||
pub use logging::*;
|
||||
|
|
|
@ -131,11 +131,11 @@ pub fn render_to_stream_with_prefix(
|
|||
var start = document.getElementById("_{fragment_id}o");
|
||||
var end = document.getElementById("_{fragment_id}c");
|
||||
var range = new Range();
|
||||
range.setStartBefore(start.nextSibling);
|
||||
range.setEndAfter(end.previousSibling);
|
||||
range.setStartBefore(start.nextSibling.nextSibling);
|
||||
range.setEndAfter(end.previousSibling.previousSibling);
|
||||
range.deleteContents();
|
||||
var tpl = document.getElementById("{fragment_id}f");
|
||||
end.parentNode.insertBefore(tpl.content.cloneNode(true), end);
|
||||
end.parentNode.insertBefore(tpl.content.cloneNode(true), end.previousSibling);
|
||||
</script>
|
||||
"#
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue