javascript React Flow:如何删除元素?

mu0hgdu0  于 2023-02-07  发布在  Java
关注(0)|答案(3)|浏览(309)

我在通过按钮删除React流中的元素时遇到了问题。
我可以使用Backspace很好地删除元素,但该按钮只适用于第一次删除,之后它会恢复已删除的节点。
刚开始使用反作用流,我不能把我的手指放在这个问题上。状态没有得到一些改变吗?
下面是我用于react flow的代码
CodeSandbox here.

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;
mqxuamgl

mqxuamgl1#

我能够通过创建以下函数来实现我想要的最终结果:

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

并将其传递到OnClick:

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

将0更改为要从数组中移除的元素的索引

gojuced7

gojuced72#

从版本10开始,元素已替换为节点和边。
我可以使用下面的函数实现以下功能。

const deleteNodeById = (id) => {
    flowInstance.setNodes((nds) => nds.filter((node) => node.id !== id))
  }

并将此函数传递给我的删除按钮(在我的情况下是mui删除图标)

<DeleteOutlined
 onClick={() => deleteNodeById(data.id)}
 style={{ color: '#FF0000' }}
/>
u5i3ibmn

u5i3ibmn3#

从版本11.2开始,您可以使用

reactFlowInstance.deleteElements({ nodes: nodesToDelete, edges: edgesToDelete });

优点是该方法将触发“onNodesDelete”和“onEdgesDelete”事件,以便您可以重用处理程序。
回想一下,如果您按下“backspace”按钮,也会触发这些事件。

相关问题