使用状态管理库
在本指南中,我们解释了如何将 React Flow 与状态管理库 Zustand 一起使用。我们将构建一个小型应用程序,其中每个节点都有一个颜色选择器,用于更新其背景颜色。在本指南中,我们使用 Zustand,因为我们在 React Flow 内部已经使用了它,但当然,您也可以使用其他库,例如 Redux、Recoil 或 Jotai。
正如您可能在之前的指南和示例中所见,React Flow 可以轻松地与本地组件状态一起使用,以处理图表的节点和边。当您的应用程序增长并且您想要例如从节点内部更改状态时,事情可能会变得更复杂。为了避免通过节点数据字段传递函数,您可以使用 React 上下文 或者添加状态管理库,如本指南所述。
安装 Zustand
如上所述,我们在此示例中使用 Zustand。Zustand 类似于 Redux:您有一个包含更改状态操作和访问状态挂钩的中央商店。您可以通过以下方式安装 Zustand:
npm install --save zustand
创建商店
Zustand 允许您创建一个挂钩,用于访问商店的值和函数。我们将 nodes
和 edges
以及 onNodesChange
、onEdgesChange
、onConnect
、setNodes
和 setEdges
函数放入商店中,以获得图表的交互性。
这是基本设置。现在,我们有一个包含节点和边的商店,它可以处理由 React Flow 触发的更改(拖动、选择或删除节点或边)。如果您看一下 App.tsx
文件,您会发现它非常干净。所有数据和操作现在都是商店的一部分,并且可以使用 useStore
挂钩访问。
实现颜色更改操作
我们添加一个新的 updateNodeColor
操作来更新特定节点的 data.color
字段。为此,我们将节点 ID 和新颜色传递给操作,遍历节点并使用新颜色更新匹配的节点。
updateNodeColor: (nodeId: string, color: string) => {
set({
nodes: get().nodes.map((node) => {
if (node.id === nodeId) {
// it's important to create a new object here, to inform React Flow about the changes
return { ...node, data: { ...node.data, color } };
}
return node;
}),
});
};
此新操作现在可以在 React 组件中以这种方式使用:
const updateNodeColor = useStore((s) => s.updateNodeColor);
...
<button onClick={() => updateNodeColor(nodeId, color)} />;
添加颜色选择器节点
在此步骤中,我们实现 ColorChooserNode
组件,并在用户更改颜色时调用 updateNodeColor
。颜色选择器节点的自定义部分是颜色输入。
<input
type="color"
defaultValue={data.color}
onChange={(evt) => updateNodeColor(id, evt.target.value)}
className="nodrag"
/>
我们添加 nodrag
类名,以便用户在更改颜色时不会错误地拖动节点,并在 onChange
事件处理程序中调用 updateNodeColor
。
您现在可以单击颜色选择器并更改节点的背景。