防止循环
在 validation 示例中,我们看到了如何使用 isValidConnection
回调来阻止创建某些连接。此示例展示了如何使用 getOutgoers
实用程序检查新连接是否会导致流程中的循环。
¥In the validation example, we saw how to use
the isValidConnection
callback
to prevent certain connections from being created. This example shows how to use
the getOutgoers
util to check if a new
connection would cause a cycle in the flow.
import React, { useCallback } from 'react';
import {
ReactFlow,
Background,
useNodesState,
useEdgesState,
addEdge,
getOutgoers,
useReactFlow,
ReactFlowProvider,
} from '@xyflow/react';
import '@xyflow/react/dist/style.css';
import { nodes as initialNodes, edges as initialEdges } from './initialElements';
const Flow = () => {
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
const { getNodes, getEdges } = useReactFlow();
const isValidConnection = useCallback(
(connection) => {
// we are using getNodes and getEdges helpers here
// to make sure we create isValidConnection function only once
const nodes = getNodes();
const edges = getEdges();
const target = nodes.find((node) => node.id === connection.target);
const hasCycle = (node, visited = new Set()) => {
if (visited.has(node.id)) return false;
visited.add(node.id);
for (const outgoer of getOutgoers(node, nodes, edges)) {
if (outgoer.id === connection.source) return true;
if (hasCycle(outgoer, visited)) return true;
}
};
if (target.id === connection.source) return false;
return !hasCycle(target);
},
[getNodes, getEdges],
);
const onConnect = useCallback((params) =>
setEdges((els) => addEdge(params, els)),
);
return (
<ReactFlow
nodes={nodes}
edges={edges}
onNodesChange={onNodesChange}
onEdgesChange={onEdgesChange}
onConnect={onConnect}
isValidConnection={isValidConnection}
fitView
style={{ backgroundColor: "#F7F9FB" }}
>
<Background />
</ReactFlow>
);
};
export default () => (
<ReactFlowProvider>
<Flow />
</ReactFlowProvider>
);
Last updated on