首页 > 解决方案 > React Flow:如何删除元素?

问题描述

我在通过按钮删除反应流中的元素时遇到问题。

我可以使用 Backspace 很好地删除元素,但该按钮仅适用于第一次删除,之后它会恢复已删除的节点。

使用 react-flow 的新手,在这里无法解决问题。状态没有改变吗?

下面是我用于反应流的代码

CodeSandbox 在这里

import React, { useState, useCallback, useEffect } from "react";

import ReactFlow, {
  removeElements,
  addEdge,
  Background,
} from "react-flow-renderer";

const onLoad = (reactFlowInstance) => {
  reactFlowInstance.fitView();
  console.log(reactFlowInstance.getElements());
};

const StackFlow = () => {
  const initialElements = [
    {
      id: "0",
      position: { x: 0, y: -100 },
      sourcePosition: "bottom",
      style: {
        width: 100,
        fontSize: 11,
        color: "white",
        background: "#6ec9c0",
      },
      data: {
        label: (
          <>
          <button
            className="w-md h-md border-2 border-black p-2"
            onClick={() =>
              remModelData("0")
            }
          >
            Del
          </button> <br /> <br />
            <strong>Models</strong>
          </>
        ),
      },
    },
    {
      id: "1",
      position: { x: 100, y: 50 },
      sourcePosition: "bottom",
      targetPosition: "top",
      data: {
        label: (
          <>
          <button
            className="w-md h-md border-2 border-black p-2"
            onClick={() =>
              remModelData("1")
            }
          >
            Del
          </button> <br /> <br />
            Model: <strong>1</strong> <br />
            ID: 1
          </>
        ),
      },
    },
    {
      id: "2",
      position: { x: 150, y: 250 },
      sourcePosition: "bottom",
      targetPosition: "top",
      data: {
        label: (
          <>
          <button
            className="w-md h-md border-2 border-black p-2"
            onClick={() =>
              remModelData("2")
            }
          >
            Del
          </button> <br /> <br />
            Model 1: <strong>subModel1</strong> <br />
            ID: 2
          </>
        ),
      },
    },
    {
      id: "3",
      position: { x: 250, y: 250 },
      sourcePosition: "bottom",
      targetPosition: "top",
      data: {
        label: (
          <>
          <button
            className="w-md h-md border-2 border-black p-2"
            onClick={() =>
              remModelData("3")
            }
          >
            Del
          </button> <br /> <br />
            Model 1: <strong>subModel2</strong> <br />
            ID: 3
          </>
        ),
      },
    },
    {
      id: "0-1",
      type: "step",
      source: "0",
      target: "1"
    },
    {
      id: "1-2",
      type: "step",
      source: "1",
      target: "2"
    },
    {
      id: "1-3",
      type: "step",
      source: "1",
      target: "3"
    },
  ];

  const [elements, setElements] = useState(initialElements);
  const onElementsRemove = useCallback(
    (elementsToRemove) =>
      setElements((els) => removeElements(elementsToRemove, els)),
    []
  );
  const onConnect = (params) => setElements((els) => addEdge(params, els));

  const [reactflowInstance, setReactflowInstance] = useState(null);

  useEffect(() => {
    if (reactflowInstance && elements.length > 0) {
      reactflowInstance.fitView();
    }
  }, [reactflowInstance, elements.length]);

  const remModelData = useCallback((id) => {
    let arr = elements
    var index = arr.indexOf(id);
    if (index > -1) {
      arr.splice(index, 1);
    }
    arr = arr.filter(function (obj) {
      return obj.id !== id;
    });
    console.log(arr);
    setElements(arr);
  }, []);


  return (
    <ReactFlow
      elements={elements}
      onElementsRemove={onElementsRemove}
      onConnect={onConnect}
      onLoad={onLoad}
      snapToGrid={true}
      snapGrid={[15, 15]}
    >
      <Background color="#aaa" gap={16} />
    </ReactFlow>
  );
};

function Home() {
  return (
    <>
      <div className="w-full mx-auto justify-center items-center flex">


        <div
          className="flex mt-10 flex-row items-center content-center justify-center max-h-5xl max-w-5xl py-2"
          style={{ flex: 1, width: 1000, height: 800, borderWidth: 2 }}
        >
          <StackFlow />
        </div>
      </div>
    </>
  );
}

export default Home;

标签: javascriptreactjs

解决方案


通过创建这个函数,我能够完成我想要的最终结果:

const deleteNode = (id) => {
  setElements((els) => removeElements([elements[id]], els));
};

并将其传递给 OnClick:

onClick={() => deleteNode(0)}

将 0 更改为您希望从数组中删除的元素的索引


推荐阅读