Blog

Keep up to date with the latest news

使用状态管理库

使用状态管理库

¥Using a State Management Library

对于本指南,我们假设你已经了解 React Flow 的 核心概念 以及如何实现 自定义节点。你还应该熟悉状态管理库的概念及其使用方法。

¥For this guide we assume that you already know about the core

concepts of React Flow and how to implement

custom nodes. You should also be familiar

with the concepts of state management libraries and how to use them.

在本指南中,我们将解释如何将 React Flow 与状态管理库 Zustand 一起使用。我们将构建一个小型应用,其中每个节点都有一个颜色选择器来更新其背景颜色。我们选择 Zustand 作为本指南,因为 React Flow 已经在内部使用它,但你可以轻松使用其他状态管理库,如 Redux 、Recoil 或 Jotai

¥In this guide, we explain how to use React Flow with the state management library Zustand . We will build a small app where each node features a color chooser that updates its background color. We chose Zustand for this guide because React Flow already uses it internally, but you can easily use other state management libraries such as Redux , Recoil or Jotai

如前面的指南和示例所示,React Flow 可以轻松地与本地组件状态一起使用,以管理图中的节点和边。但是,随着应用的增长,你需要从单个节点内更新状态,管理此状态会变得更加复杂。你可以使用 React 上下文 或集成状态管理库(如 Zustand),而不是通过节点的数据字段传递函数,如本指南中所述。

¥As demonstrated in previous guides and examples, React Flow can easily be used with a local component state to manage nodes and edges in your diagram. However, as your application grows and you need to update the state from within individual nodes, managing this state can become more complex. Instead of passing functions through the node’s data field, you can use a React context or integrate a state management library like Zustand, as outlined in this guide.

安装 Zustand

¥Install Zustand

如上所述,我们在此示例中使用 Zustand。Zustand 有点像 Redux:你有一个中央存储库,其中包含用于更改状态的操作和用于访问状态的钩子。你可以通过以下方式安装 Zusand:

¥As mentioned above we are using Zustand in this example. Zustand is a bit like Redux: you have a central store with actions to alter your state and hooks to access your state. You can install Zustand via:

npmpnpmyarnbunnpm install --save zustandpnpm add zustandyarn add zustandbun add zustand

创建存储

¥Create a Store

Zustand 让你创建一个钩子来访问存储的值和功能。我们将 nodes 和 edges 以及 onNodesChange、onEdgesChange、onConnect、setNodes 和 setEdges 函数放在存储中以获得我们图表的基本交互性:

¥Zustand lets you create a hook for accessing the values and functions of your store. We put the nodes and edges and the onNodesChange, onEdgesChange, onConnect, setNodes and setEdges functions in the store to get the basic interactivity for our graph:

Open in StackblitzOpen in CodesandboxApp.tsxedges.tsindex.cssindex.htmlindex.tsxnodes.tsstore.tstypes.tsimport React from 'react';

import { useShallow } from 'zustand/react/shallow';

import { ReactFlow } from '@xyflow/react';

import '@xyflow/react/dist/style.css';

import useStore from './store';

const selector = (state) => ({

nodes: state.nodes,

edges: state.edges,

onNodesChange: state.onNodesChange,

onEdgesChange: state.onEdgesChange,

onConnect: state.onConnect,

});

function Flow() {

const { nodes, edges, onNodesChange, onEdgesChange, onConnect } = useStore(

useShallow(selector),

);

return (

nodes={nodes}

edges={edges}

onNodesChange={onNodesChange}

onEdgesChange={onEdgesChange}

onConnect={onConnect}

fitView

/>

);

}

export default Flow;

这是基本设置。我们现在有一个带有节点和边的存储,可以处理由 React Flow 触发的更改(拖动、选择或删除节点或边)。当你查看 App.tsx 文件时,你会看到它保持干净整洁。所有数据和操作现在都是存储的一部分,可以通过 useStore 钩子访问。

¥That’s the basic setup. We now have a store with nodes and edges that can handle the changes (dragging, selecting or removing a node or edge) triggered by React Flow. When you take a look at the App.tsx file, you can see that it’s kept nice and clean. All the data and actions are now part of the store and can be accessed with the useStore hook.

实现颜色更改操作

¥Implement a Color Change Action

我们添加了一个新的 updateNodeColor 操作来更新特定节点的 data.color 字段。为此,我们将节点 ID 和新颜色传递给操作,遍历节点并使用新颜色更新匹配的节点:

¥We add a new updateNodeColor action to update the data.color field of a specific node. For this we pass the node id and the new color to the action, iterate over the nodes and update the matching one with the new color:

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 组件中使用这个新操作,如下所示:

¥This new action can now be used in a React component like this:

const updateNodeColor = useStore((s) => s.updateNodeColor);

...