diff --git a/__tests__/testLoop.html b/__tests__/testLoop.html index 06bacb28..48f3d384 100644 --- a/__tests__/testLoop.html +++ b/__tests__/testLoop.html @@ -30,9 +30,9 @@ const [s, setS] = useState(0); const [b, setB] = useState(0) - console.log('s', s); + console.warn('s', s); - console.log('b', b); + console.warn('b', b); if (s < 5 && s >= 0) { setS(s + 1); @@ -43,18 +43,18 @@ } useLayoutEffect(() => { - console.log('useLayoutEffect', s); + console.warn('useLayoutEffect', s); return () => { - console.log('useLayoutEffect return', s); + console.warn('useLayoutEffect return', s); } }, [s, b]) useEffect(() => { - console.log('useEffect', s); + console.warn('useEffect', s); return () => { - console.log('useEffect return', s); + console.warn('useEffect return', s); } }, [s, b]) diff --git a/package.json b/package.json index 6007559a..93e5fc0b 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "packageManager": "pnpm@9.12.0", "scripts": { "dev:ssr": "cd ./ui/ssr-example && pnpm run dev", + "dev:ssr-inspect": "cd ./ui/ssr-example && pnpm run dev:inspect", "dev:csr": "cd ./ui/csr-example && pnpm run dev", "dev:next": "cd ./ui/next-example && pnpm run dev", "dev:vite": "cd ./ui/vite-example && pnpm run dev", diff --git a/packages/myreact-dom/src/client/api/create/feature.ts b/packages/myreact-dom/src/client/api/create/feature.ts index 112843f9..ce84b25a 100644 --- a/packages/myreact-dom/src/client/api/create/feature.ts +++ b/packages/myreact-dom/src/client/api/create/feature.ts @@ -1,6 +1,7 @@ import { NODE_TYPE, getStackTree } from "@my-react/react-reconciler"; import { PATCH_TYPE, include, remove } from "@my-react/react-shared"; +import { getPreviousHydratedNode } from "@my-react-dom-client/dispatchMount"; import { validDomTag, type DomComment, @@ -55,7 +56,7 @@ export const create = (fiber: MyReactFiberNode, renderDispatch: ClientDomDispatc try { if (hydrate) { - const previousDom = renderDispatch._previousNativeNode; + const previousDom = getPreviousHydratedNode(); const result = hydrateCreate(fiber, parentFiberWithNode || renderDispatch, previousDom); diff --git a/packages/myreact-dom/src/client/dispatchMount/feature.ts b/packages/myreact-dom/src/client/dispatchMount/feature.ts index 67763ec4..d5da90b1 100644 --- a/packages/myreact-dom/src/client/dispatchMount/feature.ts +++ b/packages/myreact-dom/src/client/dispatchMount/feature.ts @@ -16,6 +16,10 @@ import type { ClientDomDispatch } from "@my-react-dom-client/renderDispatch"; const { currentRenderPlatform } = __my_react_internal__; +let currentHydratedNode: ChildNode | null = null; + +export const getPreviousHydratedNode = () => currentHydratedNode; + // TODO /** * @internal @@ -46,7 +50,7 @@ export const clientDispatchMount = (_fiber: MyReactFiberNode, _dispatch: ClientD let _final = _hydrate; if (_fiber.nativeNode) { - _dispatch._previousNativeNode = null; + currentHydratedNode = null; } if (_fiber.child) _final = mountCommit(_fiber.child, _result); @@ -60,9 +64,9 @@ export const clientDispatchMount = (_fiber: MyReactFiberNode, _dispatch: ClientD if (_fiber.nativeNode) { // current child have loop done, so it is safe to fallback here - fallback(_dispatch._previousNativeNode?.nextSibling); + fallback(currentHydratedNode?.nextSibling); - _dispatch._previousNativeNode = _fiber.nativeNode as ChildNode; + currentHydratedNode = _fiber.nativeNode as ChildNode; } if (_fiber.sibling) { @@ -87,8 +91,6 @@ export const clientDispatchMount = (_fiber: MyReactFiberNode, _dispatch: ClientD mountCommit(_fiber, _hydrate); - delete _dispatch._previousNativeNode; - beforeSyncUpdate(); _list.listToFoot(function invokeLayoutEffectList(fiber) { layoutEffect(fiber, _dispatch); diff --git a/packages/myreact-dom/src/client/renderDispatch/instance.ts b/packages/myreact-dom/src/client/renderDispatch/instance.ts index 8df29776..fd0e02d4 100644 --- a/packages/myreact-dom/src/client/renderDispatch/instance.ts +++ b/packages/myreact-dom/src/client/renderDispatch/instance.ts @@ -56,8 +56,6 @@ export class ClientDomDispatch extends CustomRenderDispatch { runtimeRef = runtimeRef; - _previousNativeNode: null | ChildNode = null; - _runtimeError: { value: any; stack: string; source?: MyReactFiberNode }[]; isHydrateRender: boolean; diff --git a/packages/myreact-dom/src/noop/renderDispatch/noopDispatch.ts b/packages/myreact-dom/src/noop/renderDispatch/noopDispatch.ts index b9a12e33..23858474 100644 --- a/packages/myreact-dom/src/noop/renderDispatch/noopDispatch.ts +++ b/packages/myreact-dom/src/noop/renderDispatch/noopDispatch.ts @@ -1,4 +1,4 @@ -import { CustomRenderDispatch, NODE_TYPE } from "@my-react/react-reconciler"; +import { CustomRenderDispatch, getElementName, NODE_TYPE } from "@my-react/react-reconciler"; import { append, create, update } from "@my-react-dom-server/api"; import { resolveLazyElementLatest, resolveLazyElementLegacy } from "@my-react-dom-server/renderDispatch/lazy"; @@ -41,6 +41,22 @@ export class NoopLegacyRenderDispatch extends CustomRenderDispatch { hydrateTime: number | null; + findFiberByName(name: string) { + const res: MyReactFiberNode[] = []; + + const loop = (fiber: MyReactFiberNode) => { + if (getElementName(fiber).includes(name)) { + res.push(fiber); + } + fiber.child && loop(fiber.child); + fiber.sibling && loop(fiber.sibling); + }; + + loop(this.rootFiber); + + return res; + } + pendingRef(_fiber: MyReactFiberNode): void { void 0; } @@ -116,6 +132,22 @@ export class NoopLatestRenderDispatch extends CustomRenderDispatch { hydrateTime: number | null; + findFiberByName(name: string) { + const res: MyReactFiberNode[] = []; + + const loop = (fiber: MyReactFiberNode) => { + if (getElementName(fiber).includes(name)) { + res.push(fiber); + } + fiber.child && loop(fiber.child); + fiber.sibling && loop(fiber.sibling); + }; + + loop(this.rootFiber); + + return res; + } + pendingRef(_fiber: MyReactFiberNode): void { void 0; } diff --git a/packages/myreact-reconciler/src/share/debug.ts b/packages/myreact-reconciler/src/share/debug.ts index dd3484db..7563ccec 100644 --- a/packages/myreact-reconciler/src/share/debug.ts +++ b/packages/myreact-reconciler/src/share/debug.ts @@ -61,78 +61,65 @@ export const originalWarn = console.warn; export const originalError = console.error; +let warnFiber: MyReactFiberNode | null = null; + +let errorFiber: MyReactFiberNode | null = null; + export const devWarn = (...args) => { const renderPlatform = currentRenderPlatform.current; - const renderFiber = currentCallingFiber.current || currentScopeFiber.current || currentRunningFiber.current; + const renderFiber = warnFiber || currentCallingFiber.current || currentScopeFiber.current || currentRunningFiber.current; renderFiber && fiberWarn(renderFiber as MyReactFiberNode, ...args); - if (!renderFiber || args.some((i) => typeof i === "object" || i === null || i === undefined)) { - originalWarn.call(console, ...args); + const treeLog = renderFiber ? renderPlatform.getFiberTree(renderFiber) : ""; - return; - } + const obj = []; + + const log = args.map((i) => (typeof i === "object" ? (obj.push(i), "%o") : i)).join("") + treeLog; - if (enableFiberForLog.current) { - originalWarn.call(console, ...args, ...[renderPlatform.getFiberTree(renderFiber), "\n ", renderFiber]); + if (enableFiberForLog.current && renderFiber) { + originalWarn.call(console, log + "\n%o", ...obj, renderFiber); } else { - originalWarn.call(console, ...args, renderPlatform.getFiberTree(renderFiber)); + originalWarn.call(console, log); } }; export const devWarnWithFiber = (fiber: MyReactFiberNode, ...args) => { - const renderPlatform = currentRenderPlatform.current; + warnFiber = fiber; - fiberWarn(fiber, ...args); + devWarn(...args); - if (args.some((i) => typeof i === "object" || i === null || i === undefined)) { - originalError.call(console, ...args, fiber); - } else { - if (enableFiberForLog.current) { - originalWarn.call(console, ...args, ...[renderPlatform.getFiberTree(fiber), "\n ", fiber]); - } else { - originalWarn.call(console, ...args, renderPlatform.getFiberTree(fiber)); - } - } + // TODO + warnFiber = null; }; export const devError = (...args) => { const renderPlatform = currentRenderPlatform.current; - const renderFiber = currentCallingFiber.current || currentScopeFiber.current || currentRunningFiber.current; + const renderFiber = errorFiber || currentCallingFiber.current || currentScopeFiber.current || currentRunningFiber.current; renderFiber && fiberError(renderFiber as MyReactFiberNode, ...args); - if (!renderFiber || args.some((i) => typeof i === "object" || i === null || i === undefined)) { - originalError.call(console, ...args); + const treeLog = renderFiber ? renderPlatform.getFiberTree(renderFiber) : ""; - return; - } + const obj = []; - if (enableFiberForLog.current) { - originalError.call(console, ...args, ...[renderPlatform.getFiberTree(renderFiber), "\n ", renderFiber]); + const log = args.map((i) => (typeof i === "object" ? (obj.push(i), "%o") : i)).join("") + treeLog; + + if (enableFiberForLog.current && renderFiber) { + originalError.call(console, log + "\n%o", ...obj, renderFiber); } else { - originalError.call(console, ...args, renderPlatform.getFiberTree(renderFiber)); + originalError.call(console, log); } }; export const devErrorWithFiber = (fiber: MyReactFiberNode, ...args) => { - const renderPlatform = currentRenderPlatform.current; + errorFiber = fiber; - const renderFiber = fiber; + devError(...args); - fiberError(fiber, ...args); - - if (args.some((i) => typeof i === "object" || i === null || i === undefined)) { - originalError.call(console, ...args, renderFiber); - } else { - if (enableFiberForLog.current) { - originalError.call(console, ...args, ...[renderPlatform.getFiberTree(renderFiber), "\n ", renderFiber]); - } else { - originalError.call(console, ...args, renderPlatform.getFiberTree(renderFiber)); - } - } + errorFiber = null; }; export const setLogScope = () => { @@ -342,62 +329,6 @@ export const getHookTree = ( return message + re + stack; }; -export const onceWarnWithKey = (key: string, ...args: string[]) => { - const renderPlatform = currentRenderPlatform.current; - - const renderFiber = currentCallingFiber.current || currentScopeFiber.current || currentRunningFiber.current; - - if (!renderFiber) { - if (warnMap?.[key]) return; - - warnMap[key] = true; - - devWarn(...args); - - return; - } - - const tree = renderPlatform.getFiberTree(renderFiber); - - if (warnMap?.[tree]?.[key]) return; - - warnMap[tree] = { ...warnMap?.[tree], [key]: true }; - - if (enableFiberForLog.current) { - originalWarn.call(console, ...args, ...[tree, "\n ", renderFiber]); - } else { - originalWarn.call(console, ...args, tree); - } -}; - -export const onceErrorWithKey = (key: string, ...args: string[]) => { - const renderPlatform = currentRenderPlatform.current; - - const renderFiber = currentCallingFiber.current || currentScopeFiber.current || currentRunningFiber.current; - - if (!renderFiber) { - if (errorMap?.[key]) return; - - errorMap[key] = true; - - devError(...args); - - return; - } - - const tree = renderPlatform.getFiberTree(renderFiber); - - if (errorMap?.[tree]?.[key]) return; - - errorMap[tree] = { ...errorMap?.[tree], [key]: true }; - - if (enableFiberForLog.current) { - originalError.call(console, ...args, ...[tree, "\n ", renderFiber]); - } else { - originalError.call(console, ...args, tree); - } -}; - export const onceWarnWithKeyAndFiber = (fiber: MyReactFiberNode, key: string, ...args: string[]) => { const renderPlatform = currentRenderPlatform.current; @@ -407,11 +338,11 @@ export const onceWarnWithKeyAndFiber = (fiber: MyReactFiberNode, key: string, .. warnMap[tree] = { ...warnMap?.[tree], [key]: true }; - if (enableFiberForLog.current) { - originalWarn.call(console, ...args, ...[tree, "\n ", fiber]); - } else { - originalWarn.call(console, ...args, tree); - } + warnFiber = fiber; + + devWarn(...args); + + warnFiber = null; }; export const onceErrorWithKeyAndFiber = (fiber: MyReactFiberNode, key: string, ...args: string[]) => { @@ -423,9 +354,9 @@ export const onceErrorWithKeyAndFiber = (fiber: MyReactFiberNode, key: string, . errorMap[tree] = { ...errorMap?.[tree], [key]: true }; - if (enableFiberForLog.current) { - originalError.call(console, ...args, ...[tree, "\n ", fiber]); - } else { - originalError.call(console, ...args, tree); - } + errorFiber = fiber; + + devError(...args); + + errorFiber = null; }; diff --git a/ui/ssr-example/src/client/common/LoadingBar/LoadingBar.tsx b/ui/ssr-example/src/client/common/LoadingBar/LoadingBar.tsx index 7509afcf..1c4f9872 100644 --- a/ui/ssr-example/src/client/common/LoadingBar/LoadingBar.tsx +++ b/ui/ssr-example/src/client/common/LoadingBar/LoadingBar.tsx @@ -1,25 +1,28 @@ -import { memo, forwardRef } from "react"; +import { memo, forwardRef, useEffect, useState } from "react"; import { createPortal } from "react-dom"; -import { useEffectOnce, useIsMounted } from "@client/hooks"; - import style from "./index.module.scss"; -let div: HTMLDivElement | undefined; - const _Bar = forwardRef(function Bar(_, ref) { - useEffectOnce(() => { - if (!div) { - div = document.createElement("div"); - } - div.id = "__loading_bar__"; + const [ele, setEle] = useState(); + + useEffect(() => { + const e = document.createElement("div"); + + e.id = "__loading_bar__"; + const content = document.body.querySelector("#__content__") as HTMLDivElement; - document.body.insertBefore(div, content); - }); - const isMounted = useIsMounted(); + document.body.insertBefore(e, content); + + setEle(e); + + return () => { + document.body.removeChild(e); + }; + }, []); - return isMounted ? createPortal(
, div as Element) : null; + return ele ? createPortal(
, ele as Element) : null; }); _Bar.displayName = "_Bar"; diff --git a/ui/ssr-example/src/client/component/Footer/index.tsx b/ui/ssr-example/src/client/component/Footer/index.tsx index 1825c579..3116e968 100644 --- a/ui/ssr-example/src/client/component/Footer/index.tsx +++ b/ui/ssr-example/src/client/component/Footer/index.tsx @@ -44,7 +44,7 @@ const _Footer = () => { - +