反应流中的自定义节点;创建节点后将附加数据保存到节点

2024-03-14

这是我第一次介绍反应流。我希望创建一个自定义节点,创建后,用户可以在节点中输入信息并保存/显示它。从反应流自定义节点的文档 https://reactflow.dev/docs/guides/custom-nodes/,他们有一个类似的例子,他们创建了一个TextUpdaterNode that console.logs用户输入。

我不是通过控制台记录它,而是寻找一种将信息保存到节点本身并将其显示在节点上的方法。例如,如果用户要在输入中输入“24,男性”并按“回车”键,我希望使用该信息更新节点。

我可以采取哪些方法来做到这一点?


您想要做的事情还需要更多:

你可以在这里看到活生生的例子:https://codesandbox.io/s/dank-waterfall-8jfcf4?file=/src/App.js https://codesandbox.io/s/dank-waterfall-8jfcf4?file=/src/App.js

基本上,您需要:

  • Import useNodesState来自“反应流渲染器”;
  • 您将需要使用以下内容,而不是节点的基本定义:const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
  • 然后,必须定义 onAdd,如下所示:
 const onAdd = useCallback(() => {
   const newNode = {
     id: getNodeId(),
     data: { label: `${state.name} (${state.age})` },
     position: {
       x: 0,
       y: 0 + (nodes.length + 1) * 20
     }
   };
   setNodes((nds) => nds.concat(newNode));
 }, [nodes, setNodes, state.name, state.age]);
  • 您可以包括编辑,非常类似:
  const onEdit = () => {
    setNodes((nds) =>
      nds.map((node) => {
        if (node.id === editState.id) {
          node.data = {
            ...node.data,
            label: `${node.id} - ${editState.name} (${editState.age})`
          };
        }

        return node;
      })
    );
  };
  • 最后画出流程:<ReactFlow nodes={nodes} edges={edges} onNodesChange={onNodesChange} />

整个代码如下:

import React, { useState, useCallback } from "react";
import ReactFlow, {
  ReactFlowProvider,
  useNodesState,
  useEdgesState
} from "react-flow-renderer";

import "./styles.css";

const getNodeId = () => `randomnode_${+new Date()}`;

const initialNodes = [
  { id: "1", data: { label: "Node 1" }, position: { x: 100, y: 100 } },
  { id: "2", data: { label: "Node 2" }, position: { x: 100, y: 200 } }
];

const initialEdges = [{ id: "e1-2", source: "1", target: "2" }];

const FlowExample = () => {
  const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
  const [edges] = useEdgesState(initialEdges);
  const [state, setState] = useState({ name: "", age: "" });

  const onAdd = useCallback(() => {
    const newNode = {
      id: getNodeId(),
      data: { label: `${state.name} (${state.age})` },
      position: {
        x: 0,
        y: 0 + (nodes.length + 1) * 20
      }
    };
    setNodes((nds) => nds.concat(newNode));
  }, [nodes, setNodes, state.name, state.age]);

  return (
    <div>
      Name:{" "}
      <input
        type="text"
        onChange={(e) => {
          setState((prev) => ({ ...prev, name: e.target.value }));
        }}
      />
      Age:{" "}
      <input
        type="text"
        onChange={(e) => {
          setState((prev) => ({ ...prev, age: e.target.value }));
        }}
      />
      <button onClick={onAdd}>add node</button>
      <div style={{ width: "500px", height: "500px" }}>
        <ReactFlow nodes={nodes} edges={edges} onNodesChange={onNodesChange} />
      </div>
    </div>
  );
};

export default () => (
  <ReactFlowProvider>
    <FlowExample />
  </ReactFlowProvider>
);

另外,通过编辑:

import React, { useState, useCallback } from "react";
import ReactFlow, {
  ReactFlowProvider,
  useNodesState,
  useEdgesState
} from "react-flow-renderer";

import "./styles.css";

const getNodeId = () => `${String(+new Date()).slice(6)}`;

const initialNodes = [
  { id: "1", data: { label: "Node 1" }, position: { x: 100, y: 100 } },
  { id: "2", data: { label: "Node 2" }, position: { x: 100, y: 200 } }
];

const initialEdges = [{ id: "e1-2", source: "1", target: "2" }];

const FlowExample = () => {
  const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
  const [edges] = useEdgesState(initialEdges);
  const [state, setState] = useState({ name: "", age: "" });
  const [editState, setEditState] = useState({ id: "", name: "", age: "" });

  const onEdit = () => {
    setNodes((nds) =>
      nds.map((node) => {
        if (node.id === editState.id) {
          node.data = {
            ...node.data,
            label: `${node.id} - ${editState.name} (${editState.age})`
          };
        }

        return node;
      })
    );
  };

  const onAdd = () => {
    const id = getNodeId();
    const newNode = {
      id,
      data: { label: `${id} - ${state.name} (${state.age})` },
      position: {
        x: 0,
        y: 0 + (nodes.length + 1) * 20
      }
    };
    setNodes((nds) => nds.concat(newNode));
  };

  return (
    <div>
      Name:{" "}
      <input
        type="text"
        onChange={(e) => {
          setState((prev) => ({ ...prev, name: e.target.value }));
        }}
      />
      Age:{" "}
      <input
        type="text"
        onChange={(e) => {
          setState((prev) => ({ ...prev, age: e.target.value }));
        }}
      />
      <button onClick={onAdd}>add node</button>
      <br />
      Id:{" "}
      <input
        type="text"
        onChange={(e) => {
          setEditState((prev) => ({ ...prev, id: e.target.value }));
        }}
      />
      Name:{" "}
      <input
        type="text"
        onChange={(e) => {
          setEditState((prev) => ({ ...prev, name: e.target.value }));
        }}
      />
      Age:{" "}
      <input
        type="text"
        onChange={(e) => {
          setEditState((prev) => ({ ...prev, age: e.target.value }));
        }}
      />
      <button onClick={onEdit}>Edit node</button>
      <div style={{ width: "500px", height: "500px" }}>
        <ReactFlow nodes={nodes} edges={edges} onNodesChange={onNodesChange} />
      </div>
    </div>
  );
};

export default () => (
  <ReactFlowProvider>
    <FlowExample />
  </ReactFlowProvider>
);

文档中一个更有用的示例是:

  • https://reactflow.dev/docs/examples/interaction/save-and-restore/ https://reactflow.dev/docs/examples/interaction/save-and-restore/
  • https://reactflow.dev/docs/examples/nodes/update-node/ https://reactflow.dev/docs/examples/nodes/update-node/

但你必须删除所有额外的信息(而且,你可以用它来更深入!)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

反应流中的自定义节点;创建节点后将附加数据保存到节点 的相关文章

随机推荐