fix(react): call onNodesChange for uncontrolled flows that use updateNode #5062

This commit is contained in:
moklick
2025-05-07 09:39:30 +02:00
parent 92f21356f7
commit b764875dec
2 changed files with 25 additions and 22 deletions
+6 -3
View File
@@ -11,6 +11,7 @@ import {
useReactFlow, useReactFlow,
Panel, Panel,
OnNodeDrag, OnNodeDrag,
FitViewOptions,
} from '@xyflow/react'; } from '@xyflow/react';
const onNodeDrag: OnNodeDrag = (_, node: Node, nodes: Node[]) => console.log('drag', node, nodes); const onNodeDrag: OnNodeDrag = (_, node: Node, nodes: Node[]) => console.log('drag', node, nodes);
@@ -54,6 +55,9 @@ const initialEdges: Edge[] = [
]; ];
const defaultEdgeOptions = {}; const defaultEdgeOptions = {};
const fitViewOptions: FitViewOptions = {
padding: { top: '100px', left: '0%', right: '10%', bottom: 0.1 },
};
const BasicFlow = () => { const BasicFlow = () => {
const { const {
@@ -135,6 +139,7 @@ const BasicFlow = () => {
<ReactFlow <ReactFlow
defaultNodes={initialNodes} defaultNodes={initialNodes}
defaultEdges={initialEdges} defaultEdges={initialEdges}
onNodesChange={console.log}
onNodeClick={onNodeClick} onNodeClick={onNodeClick}
onNodeDragStop={onNodeDragStop} onNodeDragStop={onNodeDragStop}
onNodeDragStart={onNodeDragStart} onNodeDragStart={onNodeDragStart}
@@ -146,9 +151,7 @@ const BasicFlow = () => {
minZoom={0.2} minZoom={0.2}
maxZoom={4} maxZoom={4}
fitView fitView
fitViewOptions={{ fitViewOptions={fitViewOptions}
padding: { top: '100px', left: '0%', right: '10%', bottom: 0.1 },
}}
defaultEdgeOptions={defaultEdgeOptions} defaultEdgeOptions={defaultEdgeOptions}
selectNodesOnDrag={false} selectNodesOnDrag={false}
elevateEdgesOnSelect elevateEdgesOnSelect
@@ -40,28 +40,28 @@ export function BatchProvider<NodeType extends Node = Node, EdgeType extends Edg
next = typeof payload === 'function' ? payload(next) : payload; next = typeof payload === 'function' ? payload(next) : payload;
} }
// When a controlled flow is used we need to collect the changes
const changes = getElementsDiffChanges({
items: next,
lookup: nodeLookup,
}) as NodeChange<NodeType>[];
if (hasDefaultNodes) { if (hasDefaultNodes) {
setNodes(next); setNodes(next);
} else { }
// When a controlled flow is used we need to collect the changes
const changes = getElementsDiffChanges({
items: next,
lookup: nodeLookup,
}) as NodeChange<NodeType>[];
// We only want to fire onNodesChange if there are changes to the nodes // We only want to fire onNodesChange if there are changes to the nodes
if (changes.length > 0) { if (changes.length > 0) {
onNodesChange?.(changes); onNodesChange?.(changes);
} else if (fitViewQueued) { } else if (fitViewQueued) {
// If there are no changes to the nodes, we still need to call setNodes // If there are no changes to the nodes, we still need to call setNodes
// to trigger a re-render and fitView. // to trigger a re-render and fitView.
window.requestAnimationFrame(() => { window.requestAnimationFrame(() => {
const { fitViewQueued, nodes, setNodes } = store.getState(); const { fitViewQueued, nodes, setNodes } = store.getState();
if (fitViewQueued) { if (fitViewQueued) {
setNodes(nodes); setNodes(nodes);
} }
}); });
}
} }
}, []); }, []);