diff --git a/packages/myreact-dom/src/client/api/helper/event/addEvent.ts b/packages/myreact-dom/src/client/api/helper/event/addEvent.ts index 404770b8..89542d27 100644 --- a/packages/myreact-dom/src/client/api/helper/event/addEvent.ts +++ b/packages/myreact-dom/src/client/api/helper/event/addEvent.ts @@ -1,5 +1,5 @@ import { __my_react_shared__ } from "@my-react/react"; -import { afterSyncUpdate, beforeSyncUpdate, safeCallWithFiber } from "@my-react/react-reconciler"; +import { afterSyncUpdate, beforeSyncUpdate, callWithFiber } from "@my-react/react-reconciler"; import { clearEvent, enableControlComponent, enableEventSystem, enableEventTrack, log, triggerEvent } from "@my-react-dom-shared"; @@ -98,7 +98,7 @@ export const addEventListener = (fiber: MyReactFiberNode, eventMap: ClientDomDis triggerEvent(eventName, fiber); } - safeCallWithFiber({ + callWithFiber({ action: function safeCallEventCallback() { eventDispatcher.cb?.call?.(null, ...args); }, diff --git a/packages/myreact-reconciler/src/runtimeFiber/instance.ts b/packages/myreact-reconciler/src/runtimeFiber/instance.ts index f8444e36..4349dd3f 100644 --- a/packages/myreact-reconciler/src/runtimeFiber/instance.ts +++ b/packages/myreact-reconciler/src/runtimeFiber/instance.ts @@ -124,13 +124,6 @@ export const prepareUpdateOnFiber = (fiber: MyReactFiberNode, renderDispatch: Cu }, }); - safeCallWithFiber({ - fiber, - action: function safeCallFiberUpdateListener() { - listenerMap.get(renderDispatch)?.fiberUpdate?.forEach((cb) => cb(fiber)); - }, - }); - if (updateState.isSync) { renderPlatform.microTask(function triggerSyncUpdateOnFiber() { triggerUpdate(fiber, updateState.isForce ? STATE_TYPE.__triggerSyncForce__ : STATE_TYPE.__triggerSync__, updateState.callback); diff --git a/packages/myreact-reconciler/src/runtimeFiber/update.ts b/packages/myreact-reconciler/src/runtimeFiber/update.ts index c21e2b0d..783dd58d 100644 --- a/packages/myreact-reconciler/src/runtimeFiber/update.ts +++ b/packages/myreact-reconciler/src/runtimeFiber/update.ts @@ -5,6 +5,7 @@ import { prepareUpdateAllDependence, /* prepareUpdateAllDependenceFromProvider, import { listenerMap } from "../renderDispatch"; import { currentRenderDispatch, NODE_TYPE, safeCallWithFiber } from "../share"; +import type { CustomRenderDispatch} from "../renderDispatch"; import type { MyReactFiberNode } from "./instance"; import type { MyReactElement, MyReactElementNode, memo } from "@my-react/react"; @@ -95,20 +96,6 @@ export const updateFiberNode = ( if (include(fiber.type, NODE_TYPE.__text__)) { renderDispatch.pendingUpdate(fiber); } - - safeCallWithFiber({ - fiber, - action: function safeCallPatchToFiberUpdate() { - renderDispatch.patchToFiberUpdate?.(fiber); - }, - }); - - safeCallWithFiber({ - fiber, - action: function safeCallFiberUpdateListener() { - listenerMap.get(renderDispatch)?.fiberUpdate?.forEach((listener) => listener(fiber)); - }, - }); } if (nextRef && prevRef !== nextRef) { @@ -125,3 +112,19 @@ export const updateFiberNode = ( return fiber; }; + +export const triggerFiberUpdateListener = (renderDispatch: CustomRenderDispatch, fiber: MyReactFiberNode) => { + safeCallWithFiber({ + fiber, + action: function safeCallPatchToFiberUpdate() { + renderDispatch.patchToFiberUpdate?.(fiber); + }, + }); + + safeCallWithFiber({ + fiber, + action: function safeCallFiberUpdateListener() { + listenerMap.get(renderDispatch)?.fiberUpdate?.forEach((listener) => listener(fiber)); + }, + }); +} \ No newline at end of file diff --git a/packages/myreact-reconciler/src/runtimeUpdate/feature.ts b/packages/myreact-reconciler/src/runtimeUpdate/feature.ts index 2a8dfea2..444a2316 100644 --- a/packages/myreact-reconciler/src/runtimeUpdate/feature.ts +++ b/packages/myreact-reconciler/src/runtimeUpdate/feature.ts @@ -1,31 +1,40 @@ import { performToNextFiberFromRoot, performToNextFiberFromTrigger } from "../renderNextWork"; +import { triggerFiberUpdateListener } from "../runtimeFiber"; import type { CustomRenderDispatch } from "../renderDispatch"; export const updateLoopSyncFromRoot = (renderDispatch: CustomRenderDispatch) => { while (renderDispatch.runtimeFiber.nextWorkingFiber) { - const nextFiber = performToNextFiberFromRoot(renderDispatch.runtimeFiber.nextWorkingFiber, renderDispatch); + const currentFiber = renderDispatch.runtimeFiber.nextWorkingFiber; + const nextFiber = performToNextFiberFromRoot(currentFiber, renderDispatch); + triggerFiberUpdateListener(renderDispatch, currentFiber); renderDispatch.runtimeFiber.nextWorkingFiber = nextFiber; } }; export const updateLoopSyncFromTrigger = (renderDispatch: CustomRenderDispatch) => { while (renderDispatch.runtimeFiber.nextWorkingFiber) { - const nextFiber = performToNextFiberFromTrigger(renderDispatch.runtimeFiber.nextWorkingFiber, renderDispatch); + const currentFiber = renderDispatch.runtimeFiber.nextWorkingFiber; + const nextFiber = performToNextFiberFromTrigger(currentFiber, renderDispatch); + triggerFiberUpdateListener(renderDispatch, currentFiber); renderDispatch.runtimeFiber.nextWorkingFiber = nextFiber; } }; export const updateLoopConcurrentFromRoot = (renderDispatch: CustomRenderDispatch) => { while (renderDispatch.runtimeFiber.nextWorkingFiber && !renderDispatch.shouldYield()) { - const nextFiber = performToNextFiberFromRoot(renderDispatch.runtimeFiber.nextWorkingFiber, renderDispatch); + const currentFiber = renderDispatch.runtimeFiber.nextWorkingFiber; + const nextFiber = performToNextFiberFromRoot(currentFiber, renderDispatch); + triggerFiberUpdateListener(renderDispatch, currentFiber); renderDispatch.runtimeFiber.nextWorkingFiber = nextFiber; } }; export const updateLoopConcurrentFromTrigger = (renderDispatch: CustomRenderDispatch) => { while (renderDispatch.runtimeFiber.nextWorkingFiber && !renderDispatch.shouldYield()) { - const nextFiber = performToNextFiberFromTrigger(renderDispatch.runtimeFiber.nextWorkingFiber, renderDispatch); + const currentFiber = renderDispatch.runtimeFiber.nextWorkingFiber; + const nextFiber = performToNextFiberFromTrigger(currentFiber, renderDispatch); + triggerFiberUpdateListener(renderDispatch, currentFiber); renderDispatch.runtimeFiber.nextWorkingFiber = nextFiber; } }; diff --git a/packages/myreact-reconciler/src/share/elementType.ts b/packages/myreact-reconciler/src/share/elementType.ts index 5904de9f..f204485a 100644 --- a/packages/myreact-reconciler/src/share/elementType.ts +++ b/packages/myreact-reconciler/src/share/elementType.ts @@ -77,14 +77,22 @@ export const getTypeFromElement = (element: MyReactElement): ReturnTypeFromEleme let finalElement = element; - const pendingProps = element.props; + let pendingProps = element.props; - const ref: MyReactElement["ref"] | null = element.ref ?? undefined; + let ref: MyReactElement["ref"] | null = element.ref ?? undefined; - const key: MyReactElement["key"] | null = element.key ?? undefined; + let key: MyReactElement["key"] | null = element.key ?? undefined; if (__DEV__ && enableHMRForDev.current) { finalElement = getElementFromRefreshIfExist(element); + + elementType = finalElement.type; + + pendingProps = finalElement.props; + + ref = finalElement.ref ?? undefined; + + key = finalElement.key ?? undefined; } if (typeof elementType === "object" && elementType !== null) { diff --git a/packages/myreact-reconciler/src/share/safeCall.ts b/packages/myreact-reconciler/src/share/safeCall.ts index a7e406d8..de9c4688 100644 --- a/packages/myreact-reconciler/src/share/safeCall.ts +++ b/packages/myreact-reconciler/src/share/safeCall.ts @@ -40,6 +40,15 @@ export const safeCallWithFiber = ( } }; +export const callWithFiber = ({ action, fiber }: { action: (...args: T) => K; fiber: MyReactFiberNode }, ...args: T): K => { + currentScopeFiber.current = fiber; + try { + return action.call(null, ...args); + } finally { + currentScopeFiber.current = null; + } +}; + export const safeCallWithSync = (action: (...args: T) => K, ...args: T): K => { currentScopeFiber.current = currentRunningFiber.current as MyReactFiberNode; try { diff --git a/ui/vite-example/src/App.tsx b/ui/vite-example/src/App.tsx index a21684dc..475db26e 100644 --- a/ui/vite-example/src/App.tsx +++ b/ui/vite-example/src/App.tsx @@ -1,16 +1,17 @@ -import { Card, MantineProvider, ScrollAreaAutosize } from "@mantine/core"; +import { Button, Card, ScrollAreaAutosize, useMantineColorScheme } from "@mantine/core"; import { useState } from "react"; import "./App.css"; import "@mantine/core/styles.css"; import { Example } from "./Example"; -import { theme } from "./theme"; function App() { const [count, setCount] = useState(0); + const { colorScheme, toggleColorScheme } = useMantineColorScheme({ keepTransitions: true }); + return ( - + <>
Vite @@ -27,13 +28,16 @@ function App() { Edit src/App.tsx and save to test HMR

+
+ +

Click on the Vite and React logos to learn more

-
+ ); } diff --git a/ui/vite-example/src/main.tsx b/ui/vite-example/src/main.tsx index 133cda1e..e8c6f5b7 100644 --- a/ui/vite-example/src/main.tsx +++ b/ui/vite-example/src/main.tsx @@ -1,12 +1,16 @@ +import { MantineProvider } from "@mantine/core"; import * as React from "react"; -import * as ReactDOM from 'react-dom/client' +import * as ReactDOM from "react-dom/client"; import App from "./App.tsx"; +import { theme } from "./theme.ts"; + import "./index.css"; -ReactDOM.createRoot(document.getElementById('root')!).render( +ReactDOM.createRoot(document.getElementById("root")!).render( - - , -) - + + + + +);