From 7d68b7c695d6be1875e751d6f355a50883a472e7 Mon Sep 17 00:00:00 2001 From: yamachu Date: Sun, 14 Sep 2025 10:06:04 +0900 Subject: [PATCH 1/3] Checkpoint from VS Code for coding agent session --- react/apps/entry-mauiblazor/src/main.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/react/apps/entry-mauiblazor/src/main.tsx b/react/apps/entry-mauiblazor/src/main.tsx index 852b45b..910e181 100644 --- a/react/apps/entry-mauiblazor/src/main.tsx +++ b/react/apps/entry-mauiblazor/src/main.tsx @@ -8,7 +8,7 @@ const BlazorMountPoint = "js-root"; const render = () => ReactDOM.createRoot(document.getElementById(BlazorMountPoint)!).render( import.meta.env.MODE === "development" ? ( - // React.StrictModeは開発モードでuseEffectを2回呼び出して、useEffectの副作用を検出するのに役に立つ + // FIXME: React.StrictModeは開発モードでuseEffectを2回呼び出して、useEffectの副作用を検出するのに役に立つ // しかしuseEffectが2回呼び出されるとuseEffectのcleanupでBlazor ComponentのDisposeが走るため、外している ) : ( From 38934d31d609b0a372cb27bf48e960061a87b063 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 14 Sep 2025 01:06:09 +0000 Subject: [PATCH 2/3] Initial plan From fe5332f0cdeed128607910a20d0c9e577b69c3f3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 14 Sep 2025 01:11:24 +0000 Subject: [PATCH 3/3] Fix React.StrictMode compatibility with Blazor components - Modified useBlazor hook to prevent double disposal in StrictMode - Enabled React.StrictMode in all environments (development and production) - Added proper disposal state checking and error handling - Removed TODO comment and conditional StrictMode usage Co-authored-by: yamachu <1955233+yamachu@users.noreply.github.com> --- react/apps/entry-mauiblazor/src/main.tsx | 10 ++-------- .../src/hooks/useBlazor.jsx | 20 ++++++++++++++++--- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/react/apps/entry-mauiblazor/src/main.tsx b/react/apps/entry-mauiblazor/src/main.tsx index 910e181..b2fa89b 100644 --- a/react/apps/entry-mauiblazor/src/main.tsx +++ b/react/apps/entry-mauiblazor/src/main.tsx @@ -7,15 +7,9 @@ const BlazorMountPoint = "js-root"; const render = () => ReactDOM.createRoot(document.getElementById(BlazorMountPoint)!).render( - import.meta.env.MODE === "development" ? ( - // FIXME: React.StrictModeは開発モードでuseEffectを2回呼び出して、useEffectの副作用を検出するのに役に立つ - // しかしuseEffectが2回呼び出されるとuseEffectのcleanupでBlazor ComponentのDisposeが走るため、外している + - ) : ( - - - - ) + ); // call from Blazor diff --git a/react/packages/interop-mauiblazor/src/hooks/useBlazor.jsx b/react/packages/interop-mauiblazor/src/hooks/useBlazor.jsx index 615ba43..63b56f5 100644 --- a/react/packages/interop-mauiblazor/src/hooks/useBlazor.jsx +++ b/react/packages/interop-mauiblazor/src/hooks/useBlazor.jsx @@ -73,11 +73,25 @@ export function useBlazor(identifier, props) { }, [props]); // This effect will run when the component is about to unmount. + // We need to handle React.StrictMode which may run this cleanup multiple times useEffect(() => () => { + // Prevent multiple disposal calls in React.StrictMode + if (isDisposedRef.current) { + return; + } + setTimeout(() => { - isDisposedRef.current = true; - if (addRootComponentPromiseRef.current) { - addRootComponentPromiseRef.current.then((rootComponent) => rootComponent.dispose()); + // Double-check disposal state in case another cleanup already ran + if (!isDisposedRef.current && addRootComponentPromiseRef.current) { + isDisposedRef.current = true; + addRootComponentPromiseRef.current.then((rootComponent) => { + // Final check before disposal to handle race conditions + if (rootComponent && typeof rootComponent.dispose === 'function') { + rootComponent.dispose(); + } + }).catch(() => { + // Ignore disposal errors in case component was already disposed + }); } }, 1000); }, []);