mcpField
R
react-flow-architecture

react-flow-architecture

github.com/existential-birds开发85530 次安装11 周前更新
代码仓库

关于 react-flow-architecture

react-flow-architecture 是面向 React Flow 应用规划的开发技能,帮助设计节点交互、规模策略、状态管理与架构,适用于节点式编辑器和工作流。

主要功能

  1. 01将交互映射到 React Flow 回调
  2. 02按节点数量选择策略
  3. 03比较本地与外部状态管理
  4. 04规划嵌套节点和视口持久化
  5. 05评估替代方案与渲染取舍

适用场景

  1. 01规划可视化工作流构建器
  2. 02为流程编辑器选择状态管理方案
  3. 03评估图规模增长时的渲染策略

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/existential-birds/beagle --skill react-flow-architecture

安装后在 Claude Code 中输入/react-flow-architecture确认已加载。

详细介绍

React Flow 架构

何时使用 React Flow

适用场景
  • 可视化编程界面
  • 工作流构建器和自动化工具
  • 图表编辑器(流程图、组织结构图)
  • 数据管道可视化
  • 思维导图工具
  • 基于节点的音频/视频编辑器
  • 决策树构建器
  • 状态机设计器
考虑其他方案
  • 简单的静态图表(直接使用 SVG 或 canvas)
  • 高强度实时协作(可能需要自定义同步层)
  • 3D 可视化(使用 Three.js、react-three-fiber)
  • 包含 1 万个以上节点的图分析(使用基于 WebGL 的方案,例如 Sigma.js)
决策工作流(关卡)

在确定技术栈或开始实施前,按以下顺序执行此流程。仅临时原型可跳过。

  1. 列出交互 — 列出主要用户操作(例如拖动、连接、删除、分组)。**通过标准:**每项操作都对应一个要实现的具体 React Flow 回调(onNodesChange、onConnect 等)。

  2. 评估规模 — 估算峰值节点数(可见画布节点数或文档总节点数)。**通过标准:**估算范围符合 节点数量指南 中的一行,并接受其中列出的策略(例如该行要求启用 onlyRenderVisibleElements 时)。

  3. 确定状态位置 — 选择本地钩子、外部存储或 Redux/其他方案。**通过标准:**用一句话说明持久化、撤销或跨界面同步将在哪里实现,或明确写明“暂时不需要”。

  4. 重新评估其他方案 — 如果用例符合 考虑其他方案 中的情况,**通过标准:**用一句话说明 React Flow 仍然适用的原因,或说明改用的其他方案。

架构模式

Package 结构(xyflow)
@xyflow/system (vanilla TypeScript)
├── Core algorithms (edge paths, bounds, viewport)
├── xypanzoom (d3-based pan/zoom)
├── xydrag, xyhandle, xyminimap, xyresizer
└── Shared types

@xyflow/react (depends on @xyflow/system)
├── React components and hooks
├── Zustand store for state management
└── Framework-specific integrations

@xyflow/svelte (depends on @xyflow/system)
└── Svelte components and stores

**影响:**核心逻辑与框架无关。贡献代码或调试时,请确认问题是否出在 @xyflow/system 或特定框架的 package 中。

状态管理方案
1. 本地状态(简单应用)
// useNodesState/useEdgesState for prototyping
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);

**优点:**简单,样板代码极少 **缺点:**状态局限于组件树

2. 外部存储(生产环境)
// Zustand store example
import { create } from 'zustand';

interface FlowStore {
  nodes: Node[];
  edges: Edge[];
  setNodes: (nodes: Node[]) => void;
  onNodesChange: OnNodesChange;
}

const useFlowStore = create<FlowStore>((set, get) => ({
  nodes: initialNodes,
  edges: initialEdges,
  setNodes: (nodes) => set({ nodes }),
  onNodesChange: (changes) => {
    set({ nodes: applyNodeChanges(changes, get().nodes) });
  },
}));

// In component
function Flow() {
  const { nodes, edges, onNodesChange } = useFlowStore();
  return <ReactFlow nodes={nodes} onNodesChange={onNodesChange} />;
}

**优点:**可在任何位置访问状态,更容易实现持久化/同步 **缺点:**需要更多设置,并且需要谨慎优化选择器

3. Redux/其他状态库
// Connect via selectors
const nodes = useSelector(selectNodes);
const dispatch = useDispatch();

const onNodesChange = useCallback((changes: NodeChange[]) => {
  dispatch(nodesChanged(changes));
}, [dispatch]);
数据流架构
User Input → Change Event → Reducer/Handler → State Update → Re-render
     ↓
[Drag node] → onNodesChange → applyNodeChanges → setNodes → ReactFlow
     ↓
[Connect]   → onConnect → addEdge → setEdges → ReactFlow
     ↓
[Delete]    → onNodesDelete → deleteElements → setNodes/setEdges → ReactFlow
子流模式(嵌套节点)
// Parent node containing child nodes
const nodes = [
  {
    id: 'group-1',
    type: 'group',
    position: { x: 0, y: 0 },
    style: { width: 300, height: 200 },
  },
  {
    id: 'child-1',
    parentId: 'group-1',  // Key: parent reference
    extent: 'parent',      // Key: constrain to parent
    position: { x: 10, y: 30 },  // Relative to parent
    data: { label: 'Child' },
  },
];

注意事项:

  • 使用 extent: 'parent' 限制拖动范围
  • 使用 expandParent: true 自动扩展父节点
  • 父节点的 z-index 会影响子节点的渲染顺序
视口持久化
// Save viewport state
const { toObject, setViewport } = useReactFlow();

const handleSave = () => {
  const flow = toObject();
  // flow.nodes, flow.edges, flow.viewport
  localStorage.setItem('flow', JSON.stringify(flow));
};

const handleRestore = () => {
  const flow = JSON.parse(localStorage.getItem('flow'));
  setNodes(flow.nodes);
  setEdges(flow.edges);
  setViewport(flow.viewport);
};

集成模式

与后端/API 集成
// Load from API
useEffect(() => {
  fetch('/api/flow')
    .then(r => r.json())
    .then(({ nodes, edges }) => {
      setNodes(nodes);
      setEdges(edges);
    });
}, []);

// Debounced auto-save
const debouncedSave = useMemo(
  () => debounce((nodes, edges) => {
    fetch('/api/flow', {
      method: 'POST',
      body: JSON.stringify({ nodes, edges }),
    });
  }, 1000),
  []
);

useEffect(() => {
  debouncedSave(nodes, edges);
}, [nodes, edges]);
与布局算法集成
import dagre from 'dagre';

function getLayoutedElements(nodes: Node[], edges: Edge[]) {
  const g = new dagre.graphlib.Graph();
  g.setGraph({ rankdir: 'TB' });
  g.setDefaultEdgeLabel(() => ({}));

  nodes.forEach((node) => {
    g.setNode(node.id, { width: 150, height: 50 });
  });

  edges.forEach((edge) => {
    g.setEdge(edge.source, edge.target);
  });

  dagre.layout(g);

  return {
    nodes: nodes.map((node) => {
      const pos = g.node(node.id);
      return { ...node, position: { x: pos.x, y: pos.y } };
    }),
    edges,
  };
}

性能扩展

节点数量指南
节点数策略
< 100默认设置
100-500启用 onlyRenderVisibleElements
500-1000简化自定义节点,减少 DOM 元素
> 1000考虑虚拟化、WebGL 替代方案
优化技巧
<ReactFlow
  // Only render nodes/edges in viewport
  onlyRenderVisibleElements={true}

  // Reduce node border radius (improves intersect calculations)
  nodeExtent={[[-1000, -1000], [1000, 1000]]}

  // Disable features not needed
  elementsSelectable={false}
  panOnDrag={false}
  zoomOnScroll={false}
/>

权衡

受控与非受控
受控非受控
更多样板代码代码更少
完全控制状态内部状态
易于持久化需要 toObject()
更适合复杂应用适合原型
连接模式
严格(默认)宽松
仅源端 → 目标端任意连接点 → 任意连接点
行为可预测更灵活
用于数据流用于图表
<ReactFlow connectionMode={ConnectionMode.Loose} />
边的渲染
默认边自定义边
渲染快速控制更多
样式有限支持任意 SVG/HTML
适用于简单场景适用于复杂标签

评论

支持 Markdown