fix: don't re-set attributes found in HTML during hydration (closes #597)

This commit is contained in:
Greg Johnston 2023-02-28 19:56:13 -05:00
parent 578853877a
commit abef12279b
2 changed files with 50 additions and 38 deletions

View file

@ -267,12 +267,12 @@ pub fn attribute_helper(
create_render_effect(cx, move |old| {
let new = f();
if old.as_ref() != Some(&new) {
attribute_expression(&el, &name, new.clone());
attribute_expression(&el, &name, new.clone(), true);
}
new
});
}
_ => attribute_expression(el, &name, value),
_ => attribute_expression(el, &name, value, false),
};
}
@ -281,39 +281,44 @@ pub(crate) fn attribute_expression(
el: &web_sys::Element,
attr_name: &str,
value: Attribute,
force: bool,
) {
match value {
Attribute::String(value) => {
let value = wasm_bindgen::intern(&value);
if attr_name == "inner_html" {
el.set_inner_html(value);
} else {
let attr_name = wasm_bindgen::intern(attr_name);
el.set_attribute(attr_name, value).unwrap_throw();
}
}
Attribute::Option(_, value) => {
if attr_name == "inner_html" {
el.set_inner_html(&value.unwrap_or_default());
} else {
let attr_name = wasm_bindgen::intern(attr_name);
match value {
Some(value) => {
let value = wasm_bindgen::intern(&value);
el.set_attribute(attr_name, value).unwrap_throw();
}
None => el.remove_attribute(attr_name).unwrap_throw(),
use crate::HydrationCtx;
if force || !HydrationCtx::is_hydrating() {
match value {
Attribute::String(value) => {
let value = wasm_bindgen::intern(&value);
if attr_name == "inner_html" {
el.set_inner_html(value);
} else {
let attr_name = wasm_bindgen::intern(attr_name);
el.set_attribute(attr_name, value).unwrap_throw();
}
}
}
Attribute::Bool(value) => {
let attr_name = wasm_bindgen::intern(attr_name);
if value {
el.set_attribute(attr_name, attr_name).unwrap_throw();
} else {
el.remove_attribute(attr_name).unwrap_throw();
Attribute::Option(_, value) => {
if attr_name == "inner_html" {
el.set_inner_html(&value.unwrap_or_default());
} else {
let attr_name = wasm_bindgen::intern(attr_name);
match value {
Some(value) => {
let value = wasm_bindgen::intern(&value);
el.set_attribute(attr_name, value).unwrap_throw();
}
None => el.remove_attribute(attr_name).unwrap_throw(),
}
}
}
Attribute::Bool(value) => {
let attr_name = wasm_bindgen::intern(attr_name);
if value {
el.set_attribute(attr_name, attr_name).unwrap_throw();
} else {
el.remove_attribute(attr_name).unwrap_throw();
}
}
_ => panic!("Remove nested Fn in Attribute"),
}
_ => panic!("Remove nested Fn in Attribute"),
}
}

View file

@ -85,12 +85,14 @@ pub fn class_helper(
create_render_effect(cx, move |old| {
let new = f();
if old.as_ref() != Some(&new) && (old.is_some() || new) {
class_expression(&class_list, &name, new)
class_expression(&class_list, &name, new, true)
}
new
});
}
Class::Value(value) => class_expression(&class_list, &name, value),
Class::Value(value) => {
class_expression(&class_list, &name, value, false)
}
};
}
@ -99,11 +101,16 @@ pub(crate) fn class_expression(
class_list: &web_sys::DomTokenList,
class_name: &str,
value: bool,
force: bool,
) {
let class_name = wasm_bindgen::intern(class_name);
if value {
class_list.add_1(class_name).unwrap_throw();
} else {
class_list.remove_1(class_name).unwrap_throw();
use crate::HydrationCtx;
if force || !HydrationCtx::is_hydrating() {
let class_name = wasm_bindgen::intern(class_name);
if value {
class_list.add_1(class_name).unwrap_throw();
} else {
class_list.remove_1(class_name).unwrap_throw();
}
}
}