API 灵活性:通过 Hooks(如 useReactFlow)和 Context API,轻松实现动态状态管理。
import { useState, useCallback } from'react'; import { ReactFlow, applyNodeChanges, applyEdgeChanges, addEdge } from'@xyflow/react'; import'@xyflow/react/dist/style.css'; // 堆代码 duidaima.com const initialNodes = [ { id: '1', position: { x: 0, y: 0 }, data: { label: 'Start' } }, { id: '2', position: { x: 200, y: 100 }, data: { label: 'Process' } }, { id: '3', position: { x: 400, y: 200 }, data: { label: 'End' } } ]; const initialEdges = [ { id: 'e1-2', source: '1', target: '2', animated: true }, { id: 'e2-3', source: '2', target: '3' } ]; exportdefaultfunction App() { const [nodes, setNodes] = useState(initialNodes); const [edges, setEdges] = useState(initialEdges); const onNodesChange = useCallback( (changes) => setNodes((nodesSnapshot) => applyNodeChanges(changes, nodesSnapshot)), [], ); const onEdgesChange = useCallback( (changes) => setEdges((edgesSnapshot) => applyEdgeChanges(changes, edgesSnapshot)), [], ); const onConnect = useCallback( (params) => setEdges((edgesSnapshot) => addEdge(params, edgesSnapshot)), [], ); return ( <div style={{ width: '100vw', height: '100vh' }}> <ReactFlow nodes={nodes} edges={edges} onNodesChange={onNodesChange} onEdgesChange={onEdgesChange} onConnect={onConnect} fitView /> </div> ); }注释:
自定义扩展:自定义节点和边作为 React 组件,支持集成 Tailwind CSS、Emotion 或 D3.js,实现复杂样式和动画。
import ReactFlow, { Handle, Position } from'@xyflow/react'; const CustomNode = ({ data }) => ( <div style={{ padding: 10, border: '1px solid #777', borderRadius: 5, background: '#f0f0f0' }}> <Handle type="target" position={Position.Left} /> {/* 输入端口 */} <input value={data.label} onChange={(e) => data.onChange?.(e.target.value)} style={{ width: '100px' }} /> <Handle type="source" position={Position.Right} /> {/* 输出端口 */} </div> ); const nodeTypes = { custom: CustomNode }; exportdefaultfunction CustomFlow() { const initialNodes = [ { id: '1', type: 'custom', position: { x: 0, y: 0 }, data: { label: 'Input Node', onChange: (value) =>console.log('New value:', value) } } ]; return ( <div style={{ width: '100%', height: '500px' }}> <ReactFlow nodes={initialNodes} nodeTypes={nodeTypes} /> </div> ); }Handle 定义节点的连接点,nodeTypes 映射确保自定义节点正确渲染。
社区插件:如 react-flow-renderer-nns(社区扩展,优化大规模节点)。
import { useCallback, useState } from'react'; import ReactFlow, { useNodesState, useEdgesState, addEdge, Connection, Handle, Position } from'@xyflow/react'; import'@xyflow/react/dist/style.css'; const AINode = ({ data }) => ( <div style={{ padding: 15, border: '2px solid #333', borderRadius: 8, background: '#fff' }}> <Handle type="target" position={Position.Top} /> <div style={{ fontWeight: 'bold' }}>{data.label}</div> <Handle type="source" position={Position.Bottom} /> </div> ); const nodeTypes = { aiNode: AINode }; exportdefaultfunction AIBuilder() { const [nodes, setNodes, onNodesChange] = useNodesState([ { id: '1', type: 'aiNode', position: { x: 0, y: 0 }, data: { label: 'User Prompt' } }, { id: '2', type: 'aiNode', position: { x: 200, y: 100 }, data: { label: 'OpenAI API' } }, { id: '3', type: 'aiNode', position: { x: 400, y: 200 }, data: { label: 'Tool Call' } } ]); const [edges, setEdges, onEdgesChange] = useEdgesState([]); const onConnect = useCallback((params: Connection) => setEdges((eds) => addEdge({ ...params, animated: true }, eds)), [setEdges]); const onSave = useCallback(() => { const flow = { nodes, edges }; localStorage.setItem('ai-flow', JSON.stringify(flow)); // 保存到本地 console.log('Workflow:', flow); // 可发送到后端集成 OpenAI API }, [nodes, edges]); return ( <div style={{ width: '100%', height: '600px' }}> <button onClick={onSave} style={{ marginBottom: 10 }}>Save Workflow</button> <ReactFlow nodes={nodes} edges={edges} onNodesChange={onNodesChange} onEdgesChange={onEdgesChange} onConnect={onConnect} nodeTypes={nodeTypes} fitView > <Controls /> <Background /> </ReactFlow> </div> ); }总结