mirror of
https://github.com/chenasraf/leptos.git
synced 2026-05-18 01:49:06 +00:00
Fixes for <Suspense/> hydration
This commit is contained in:
@@ -93,19 +93,16 @@ where
|
||||
use leptos_dom::DynChild;
|
||||
|
||||
Component::new("Suspense", move |cx| {
|
||||
let cached_id = HydrationCtx::peek();
|
||||
let mut cached_id = HydrationCtx::peek();
|
||||
let mut id_to_replace = cached_id.clone();
|
||||
id_to_replace.offset += 0;
|
||||
|
||||
DynChild::new(move || {
|
||||
let mut id_to_replace = cached_id.clone();
|
||||
id_to_replace.offset += 2;
|
||||
if context.ready() {
|
||||
HydrationCtx::continue_from(id_to_replace);
|
||||
|
||||
if context.ready() {
|
||||
child(cx).into_view(cx)
|
||||
} else {
|
||||
fallback().into_view(cx)
|
||||
}
|
||||
})
|
||||
child(cx).into_view(cx)
|
||||
} else {
|
||||
fallback().into_view(cx)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -125,32 +122,37 @@ where
|
||||
let orig_child = Rc::clone(&orig_child);
|
||||
|
||||
Component::new("Suspense", move |cx| {
|
||||
DynChild::new(move || {
|
||||
let current_id = HydrationCtx::peek();
|
||||
let current_id = HydrationCtx::peek();
|
||||
|
||||
// run the child; we'll probably throw this away, but it will register resource reads
|
||||
let child = orig_child(cx).into_view(cx);
|
||||
// run the child; we'll probably throw this away, but it will register resource reads
|
||||
let child = orig_child(cx).into_view(cx);
|
||||
|
||||
let initial = {
|
||||
// no resources were read under this, so just return the child
|
||||
if context.pending_resources.get() == 0 {
|
||||
child.clone()
|
||||
}
|
||||
// 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(), move || {
|
||||
let initial = {
|
||||
// no resources were read under this, so just return the child
|
||||
if context.pending_resources.get() == 0 {
|
||||
child.clone()
|
||||
}
|
||||
// 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();
|
||||
move || {
|
||||
HydrationCtx::continue_from(current_id);
|
||||
orig_child(cx)
|
||||
.into_view(cx)
|
||||
.render_to_string(cx)
|
||||
.to_string()
|
||||
});
|
||||
|
||||
// return the fallback for now, wrapped in fragment identifer
|
||||
fallback().into_view(cx)
|
||||
}
|
||||
};
|
||||
initial
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
// return the fallback for now, wrapped in fragment identifer
|
||||
fallback().into_view(cx)
|
||||
}
|
||||
};
|
||||
|
||||
HydrationCtx::continue_from(current_id);
|
||||
|
||||
initial
|
||||
})
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@ use std::{
|
||||
future::Future,
|
||||
pin::Pin,
|
||||
};
|
||||
use cfg_if::cfg_if;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct SharedContext {
|
||||
pub events: Vec<()>,
|
||||
pub pending_resources: HashSet<ResourceId>,
|
||||
@@ -29,6 +29,43 @@ impl PartialEq for SharedContext {
|
||||
|
||||
impl Eq for SharedContext {}
|
||||
|
||||
impl SharedContext {
|
||||
impl Default for SharedContext {
|
||||
|
||||
}
|
||||
fn default() -> Self {
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "hydrate")] {
|
||||
let pending_resources = js_sys::Reflect::get(
|
||||
&web_sys::window().unwrap(),
|
||||
&wasm_bindgen::JsValue::from_str("__LEPTOS_PENDING_RESOURCES"),
|
||||
);
|
||||
let pending_resources: HashSet<ResourceId> = pending_resources
|
||||
.map_err(|_| ())
|
||||
.and_then(|pr| serde_wasm_bindgen::from_value(pr).map_err(|_| ()))
|
||||
.unwrap_or_default();
|
||||
|
||||
let resolved_resources = js_sys::Reflect::get(
|
||||
&web_sys::window().unwrap(),
|
||||
&wasm_bindgen::JsValue::from_str("__LEPTOS_RESOLVED_RESOURCES"),
|
||||
)
|
||||
.unwrap_or(wasm_bindgen::JsValue::NULL);
|
||||
|
||||
let resolved_resources =
|
||||
serde_wasm_bindgen::from_value(resolved_resources).unwrap_or_default();
|
||||
|
||||
Self {
|
||||
events: Default::default(),
|
||||
pending_resources,
|
||||
resolved_resources,
|
||||
pending_fragments: Default::default(),
|
||||
}
|
||||
} else {
|
||||
Self {
|
||||
events: Default::default(),
|
||||
pending_resources: Default::default(),
|
||||
resolved_resources: Default::default(),
|
||||
pending_fragments: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user