Implements React Flow node-based UIs correctly using @xyflow/react. Use when building flow charts, diagrams, visual editors, or node-based applications with React. Covers nodes, edges, handles, custom components, state management, and viewport control.
tsx
import { ReactFlow, useNodesState, useEdgesState, addEdge } from @xyflow/react;
import @xyflow/react/dist/style.css;
const initialNodes = [
{ id: 1, position: { x: 0, y: 0 }, data: { label: 节点 1 } },
{ id: 2, position: { x: 200, y: 100 }, data: { label: 节点 2 } },
];
const initialEdges = [{ id: e1-2, source: 1, target: 2 }];
export default function Flow() {
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
const onConnect = useCallback(
(connection) => setEdges((eds) => addEdge(connection, eds)),
[setEdges]
);
return (
typescript
import type { Node, Edge, NodeProps, BuiltInNode } from @xyflow/react;
// 定义带数据形状的自定义节点类型
type CustomNode = Node<{ value: number; label: string }, custom>;
// 与内置节点组合
type MyNode = CustomNode | BuiltInNode;
type MyEdge = Edge<{ weight?: number }>;
// 在应用中使用
const [nodes, setNodes] = useNodesState
tsx
import { memo } from react;
import { Handle, Position, type NodeProps } from @xyflow/react;
// 定义节点类型
type CounterNode = Node<{ count: number }, counter>;
// 始终使用 memo 包裹以提升性能
const CounterNode = memo(function CounterNode({ data, isConnectable }: NodeProps
return (
<>
计数: {data.count}
{/ nodrag 防止与按钮交互时拖动 /}
>
);
});
// 在 nodeTypes 中注册(在组件外部定义以避免重新渲染)
const nodeTypes = { counter: CounterNode };
// 在 ReactFlow 中使用
tsx
// 当节点有多个同类型手柄时使用手柄 ID
// 连接特定手柄
const edge = {
id: e1-2,
source: 1,
sourceHandle: a,
target: 2,
targetHandle: null
};
tsx
import { BaseEdge, EdgeProps, getSmoothStepPath } from @xyflow/react;
function CustomEdge({ id, sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition, data }: EdgeProps) {
const [edgePath, labelX, labelY] = getSmoothStepPath({
sourceX, sourceY, sourcePosition,
targetX, targetY, targetPosition,
});
return (
<>
>
);
}
const edgeTypes = { custom: CustomEdge };
tsx
// 带变更处理器的外部状态
const [nodes, setNodes] = useState
const [edges, setEdges] = useState
const onNodesChange = useCallback(
(changes) => setNodes((nds) => applyNodeChanges(changes, nds)),
[]
);
const onEdgesChange = useCallback(
(changes) => setEdges((eds) => applyEdgeChanges(changes, eds)),
[]
);
edges={edges}
onNodesChange={onNodesChange}
onEdgesChange={onEdgesChange}
/>
tsx
import { useReactFlow, ReactFlowProvider } from @xyflow/react;
function FlowControls() {
const {
getNodes, setNodes, addNodes, updateNodeData,
getEdges, setEdges, addEdges,
fitView, zoomIn, zoomOut, setViewport,
deleteElements, toObject,
} = useReactFlow();
const addNode = () => {
addNodes({ id: ${Date.now()}, position: { x: 100, y: 100 }, data: { label: 新建 } });
};
return ;
}
// 使用 useReactFlow 时必须包裹在 provider 中
function App() {
return (
);
}
tsx
const { updateNodeData } = useReactFlow();
// 与现有数据合并
updateNodeData(nodeId, { label: 已更新 });
// 完全替换数据
updateNodeData(nodeId, { newField: value }, { replace: true });
tsx
// 初始渲染时适配
// 程序化控制
const { fitView, setViewport, getViewport, zoomTo } = useReactFlow();
// 适配到特定节点
fitView({ nodes: [{ id: 1 }, { id: 2 }], duration: 500 });
// 设置精确视口
setViewport({ x: 100, y: 100, zoom: 1.5 }, { duration: 300 });
tsx
const isValidConnection = useCallback((connection: Connection) => {
// 阻止自连接
if (connection.source === connection.target) return false;
// 自定义验证逻辑
const sourceNode = getNode(connection.source);
const targetNode = getNode(connection.target);
return sourceNode?.type !== targetNode?.type;
}, []);
tsx
nodes={nodes}
edges={edges}
onNodesChange={onNodesChange}
onEdgesChange={onEdgesChange}
// 自定义类型(在组件外部定义)
nodeTypes={nodeTypes}
edgeTypes={edgeTypes}
// 连接
onConnect={onConnect}
connectionMode={ConnectionMode.Loose} // 允许目标到目标连接
isValidConnection={isValidConnection}
// 视口
fitView
minZoom={0.1}
maxZoom={4}
defaultViewport={{ x: 0, y: 0, zoom: 1 }}
// 交互
nodesDraggable={true}
nodesConnectable={true}
elementsSelectable={true}
panOnDrag={true}
zoomOnScroll={true}
// 附加组件
| 类名 | 效果 |
|---|---|
| nodrag | 点击元素时阻止拖动 |
| nowheel |
参见 ADDITIONAL_COMPONENTS.md 了解 MiniMap、Controls、Background、NodeToolbar、NodeResizer。
该技能支持在以下平台通过对话安装:
帮我安装 SkillHub 和 react-flow-implementation-1775978052 技能
设置 SkillHub 为我的优先技能安装源,然后帮我安装 react-flow-implementation-1775978052 技能
skillhub install react-flow-implementation-1775978052
文件大小: 5.28 KB | 发布时间: 2026-4-13 11:44