From 949ce704268212a278974c83259efd86fc8f1e66 Mon Sep 17 00:00:00 2001 From: moklick Date: Tue, 5 May 2026 16:39:20 +0200 Subject: [PATCH 1/3] chore(store-updater): use useEffect again --- packages/react/src/components/StoreUpdater/index.tsx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/react/src/components/StoreUpdater/index.tsx b/packages/react/src/components/StoreUpdater/index.tsx index a22895a41..e02938a4d 100644 --- a/packages/react/src/components/StoreUpdater/index.tsx +++ b/packages/react/src/components/StoreUpdater/index.tsx @@ -3,11 +3,10 @@ * We distinguish between values we can update directly with `useDirectStoreUpdater` (like `snapGrid`) * and values that have a dedicated setter function in the store (like `setNodes`). */ -import { useRef } from 'react'; +import { useEffect, useRef } from 'react'; import { shallow } from 'zustand/shallow'; import { infiniteExtent, type CoordinateExtent, mergeAriaLabelConfig, AriaLabelConfig } from '@xyflow/system'; -import { useIsomorphicLayoutEffect } from '../../hooks/useIsomorphicLayoutEffect'; import { useStore, useStoreApi } from '../../hooks/useStore'; import type { Node, Edge, ReactFlowState, ReactFlowProps, FitViewOptions } from '../../types'; import { defaultNodeOrigin } from '../../container/ReactFlow/init-values'; @@ -131,7 +130,7 @@ export function StoreUpdater remount. - useIsomorphicLayoutEffect(() => { + useEffect(() => { setDefaultNodesAndEdges(props.defaultNodes, props.defaultEdges); return () => { @@ -143,7 +142,7 @@ export function StoreUpdater>>(initPrevValues); - useIsomorphicLayoutEffect( + useEffect( () => { for (const fieldName of fieldsToTrack) { const fieldValue = props[fieldName]; From eff2ca3569878e16618deaff4e2a01af7a1e7c92 Mon Sep 17 00:00:00 2001 From: moklick Date: Tue, 5 May 2026 16:40:56 +0200 Subject: [PATCH 2/3] chore(store-updater): cleanup --- packages/react/src/components/StoreUpdater/index.tsx | 5 ----- 1 file changed, 5 deletions(-) diff --git a/packages/react/src/components/StoreUpdater/index.tsx b/packages/react/src/components/StoreUpdater/index.tsx index e02938a4d..223e62bc2 100644 --- a/packages/react/src/components/StoreUpdater/index.tsx +++ b/packages/react/src/components/StoreUpdater/index.tsx @@ -125,11 +125,6 @@ export function StoreUpdater(); - // We use layout effects here so that the store is always populated before - // any child useEffect or useLayoutEffect fires. With regular useEffect, the - // cleanup calls reset() which empties the store, and child effects can run - // before the new mount effect repopulates it — causing children to read - // empty nodeLookup/nodes/edges during a remount. useEffect(() => { setDefaultNodesAndEdges(props.defaultNodes, props.defaultEdges); From ad4d547724a1c2debf8eb7c6e117aabbfd601934 Mon Sep 17 00:00:00 2001 From: moklick Date: Tue, 5 May 2026 19:33:18 +0200 Subject: [PATCH 3/3] chore(changeset): add --- .changeset/sweet-terms-exist.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/sweet-terms-exist.md diff --git a/.changeset/sweet-terms-exist.md b/.changeset/sweet-terms-exist.md new file mode 100644 index 000000000..d0603e327 --- /dev/null +++ b/.changeset/sweet-terms-exist.md @@ -0,0 +1,5 @@ +--- +'@xyflow/react': patch +--- + +Use `useEffect` for StoreUpdater to restore previous behaviour