marker hydration fixed, but we have an off-by-one error on `id` generation

This commit is contained in:
Jose Quesada 2022-12-07 12:05:12 -06:00
parent c9b57ffa85
commit 55b691e1b0
7 changed files with 36 additions and 15 deletions

View File

@ -65,7 +65,7 @@ features = [
]
[features]
default = ["web", "hydrate"]
default = ["ssr", "hydrate"]
web = []
csr = ["leptos_reactive/csr"]
hydrate = ["leptos_reactive/hydrate"]

View File

@ -14,6 +14,8 @@ pub fn App(cx: Scope) -> View {
#[component]
pub fn ComponentA(cx: Scope) -> View {
let (value, set_value) = create_signal(cx, "Hello?".to_string());
let (counter, set_counter) = create_signal(cx, 0);
div(cx)
.child(
input(cx)
@ -22,6 +24,7 @@ pub fn ComponentA(cx: Scope) -> View {
.on(ev::input, move |e| set_value(event_target_value(&e))),
)
.child(input(cx).attr("type", "text").prop("value", value))
.child(p(cx).child("Value: ").child(value))
.into_view(cx)
}

View File

@ -20,14 +20,19 @@ async fn main() -> std::io::Result<()> {
}.render_to_string().to_string()
});
runtime.dispose();
format!(r#"<!DOCTYPE html>
<html>
<head>
<script type="module">import init from '/pkg/hydration_test.js'; init();</script>
</head>
<body>{html}</body>
</html>
"#)
let html = format!(
r#"<!DOCTYPE html>
<html>
<head>
<script type="module">import init from '/pkg/hydration_test.js'; init();</script>
</head>
<body>{html}</body>
</html>"#
);
println!("{html}");
html
})
}
)

View File

@ -66,8 +66,10 @@ impl IntoView for ComponentRepr {
#[cfg_attr(debug_assertions, instrument(level = "trace", name = "<Component />", skip_all, fields(name = %self.name)))]
fn into_view(self, _: Scope) -> View {
#[cfg(all(target_arch = "wasm32", feature = "web"))]
for child in &self.children {
mount_child(MountKind::Before(&self.closing.node), child);
if !HydrationCtx::is_hydrating() {
for child in &self.children {
mount_child(MountKind::Before(&self.closing.node), child);
}
}
View::Component(self)

View File

@ -436,6 +436,12 @@ impl<El: IntoElement> HtmlElement<El> {
let child = child.into_child(self.cx);
cfg_if! {
if #[cfg(all(target_arch = "wasm32", feature = "web"))] {
#[cfg(feature = "hydrate")]
if !HydrationCtx::is_hydrating() {
mount_child(MountKind::Append(self.element.get_element()), &child.into_view(self.cx))
}
#[cfg(not(feature = "hydrate"))]
mount_child(MountKind::Append(self.element.get_element()), &child.into_view(self.cx))
}
else {

View File

@ -8,8 +8,13 @@ use std::{
type ParentOffsetSums = Vec<(usize, usize)>;
#[cfg(feature = "hydrate")]
const HYDRATION_MODE: bool = true;
#[cfg(not(feature = "hydrate"))]
const HYDRATION_MODE: bool = false;
#[thread_local]
static mut IS_HYDRATING: bool = true;
static mut IS_HYDRATING: bool = HYDRATION_MODE;
#[thread_local]
static mut ID: usize = 0;
@ -41,7 +46,7 @@ impl HydrationCtx {
pub(crate) fn to_string(id: usize, closing: bool) -> String {
#[cfg(debug_assertions)]
return format!("_{id}{}", closing.then_some('c').unwrap_or('o'));
return format!("_{id}{}", if closing { 'c' } else { 'o' });
#[cfg(not(debug_assertions))]
return format!("_{id}");

View File

@ -186,7 +186,7 @@ impl Comment {
#[cfg(all(debug_assertions, target_arch = "wasm32", feature = "web"))]
node.set_text_content(Some(&format!(" {content} ")));
#[cfg(all(debug_assertions, target_arch = "wasm32", feature = "web"))]
#[cfg(all(target_arch = "wasm32", feature = "web"))]
{
if HydrationCtx::is_hydrating() {
let id = HydrationCtx::to_string(id, closing);
@ -196,7 +196,7 @@ impl Comment {
marker.remove();
} else {
panic!("hydration mismatch between SSR and CSR");
panic!("SSR and CSR hydration mismatch, id `{id}` not found!");
}
}
}