diff --git a/packages/myreact-dom/src/client/api/helper/attr/setAttr.ts b/packages/myreact-dom/src/client/api/helper/attr/setAttr.ts index 295f3470..1ed1eb93 100644 --- a/packages/myreact-dom/src/client/api/helper/attr/setAttr.ts +++ b/packages/myreact-dom/src/client/api/helper/attr/setAttr.ts @@ -1,3 +1,4 @@ +import { isNoProps } from "@my-react-dom-client/api/update/tool"; import { getHTMLAttrKey, getSVGAttrKey, log } from "@my-react-dom-shared"; import { XLINK_NS, XML_NS, X_CHAR } from "./namespace"; @@ -48,14 +49,20 @@ export const setAttribute = (fiber: MyReactFiberNode, el: HTMLElement, name: str return; } - try { - if (name in el && !isSVG) { + if (name in el && !isSVG && !isNoProps(el, name)) { + try { if (value === null || value === undefined || value === false) { el[name] = ""; } else { el[name] = String(value); } - } else { + } catch (e) { + if (__DEV__) { + log(fiber, "error", "setProps", `${(e as Error).message}, key: ${name}, value: ${value}`); + } + } + } else { + try { const attrKey = (isSVG ? getSVGAttrKey(name) : getHTMLAttrKey(name)) || name; if (value === null || value === undefined) { el.removeAttribute(attrKey); @@ -73,10 +80,10 @@ export const setAttribute = (fiber: MyReactFiberNode, el: HTMLElement, name: str } } } - } - } catch (e) { - if (__DEV__) { - log(fiber, "error", "setAttribute", `${(e as Error).message}, key: ${name}, value: ${value}`); + } catch (e) { + if (__DEV__) { + log(fiber, "error", "setAttribute", `${(e as Error).message}, key: ${name}, value: ${value}`); + } } } }; diff --git a/packages/myreact-dom/src/client/api/update/hydrateUpdate.ts b/packages/myreact-dom/src/client/api/update/hydrateUpdate.ts index 535ea26f..4589b099 100644 --- a/packages/myreact-dom/src/client/api/update/hydrateUpdate.ts +++ b/packages/myreact-dom/src/client/api/update/hydrateUpdate.ts @@ -1,11 +1,22 @@ import { NODE_TYPE } from "@my-react/react-reconciler"; import { PATCH_TYPE, include, remove } from "@my-react/react-shared"; -import { enableControlComponent, enableEventSystem, enableHydrateWarn, getHTMLAttrKey, getSVGAttrKey, isEvent, isProperty, isStyle, log } from "@my-react-dom-shared"; +import { + enableControlComponent, + enableEventSystem, + enableHydrateWarn, + getHTMLAttrKey, + getSVGAttrKey, + isEvent, + isProperty, + isStyle, + log, +} from "@my-react-dom-shared"; import { XLINK_NS, XML_NS, X_CHAR, addEventListener, controlElementTag, setStyle } from "../helper"; import { mountControl } from "./control"; +import { isNoProps, isSameInnerHTML } from "./tool"; import type { MyReactFiberNode } from "@my-react/react-reconciler"; import type { ClientDomDispatch } from "@my-react-dom-client/renderDispatch"; @@ -77,7 +88,7 @@ const domPropsHydrate = (fiber: MyReactFiberNode, isSVG: boolean, key: string, v dom.setAttribute(key, String(value)); } } else { - if (key in dom && !isSVG) { + if (key in dom && !isSVG && !isNoProps(dom, key)) { if (dom[key].toString() !== String(value)) { if (enableHydrateWarn.current) { log(fiber, "warn", `hydrate warning, dom '${key}' props not match from server. server: ${dom[key]}, client: ${value}`); @@ -140,12 +151,10 @@ const domInnerHTMLHydrate = (fiber: MyReactFiberNode) => { const typedProps = props["dangerouslySetInnerHTML"] as Record; - const existInnerHTML = typedDOM.innerHTML; - const incomingInnerHTML = typedProps.__html as string; - if (existInnerHTML !== incomingInnerHTML) { - // log(fiber, "warn", `hydrate error, 'innerHTML' not match from server.`); + if (!isSameInnerHTML(typedDOM, incomingInnerHTML)) { + log(fiber, "warn", `hydrate error, 'innerHTML' not match from server.`); typedDOM.innerHTML = typedProps.__html as string; } diff --git a/packages/myreact-dom/src/client/api/update/tool.ts b/packages/myreact-dom/src/client/api/update/tool.ts index fc6c02c9..6fbdef43 100644 --- a/packages/myreact-dom/src/client/api/update/tool.ts +++ b/packages/myreact-dom/src/client/api/update/tool.ts @@ -1,3 +1,5 @@ +const noProps = ['href', 'list', 'form', 'tabIndex', 'download', 'src']; + /** * @internal */ @@ -7,3 +9,21 @@ export const getAllKeys = (obj1: Record, obj2: Record { + const tempDom = document.createElement('i'); + + tempDom.innerHTML = innerHTML; + + return tempDom.innerHTML === dom.innerHTML; +} + +/** + * @internal + */ +export const isNoProps = (_ele: Element, key: string) => { + return noProps.includes(key) +} \ No newline at end of file