javascriptreactjsreact-flow

React-Flow, Edges changing place or dissapearing on creating a new Node with a button


Edges change their place, when i create a new node.

Gif example Gif showing the problem

Possible cause that I can't fix

1. ReactFlowKey is updating the website without previously saving edges as they were created, because

"Couldn't create edge for source/target handle id: "some-id"; edge id: "some-id"."

which i guess is because I cannot set the proper value to targetHandle or sourceHandle when connecting the edges with the handles.

BiDirectionalNode.tsx I created custom node in BiDirectionalNode.tsx that has 4 handles (1 on each side of the square) that are sources and targets at the same time, they have unique ids

Example :

  <Handle type="source" position={Position.Left} id="leftA" />
      <Handle type="target" position={Position.Left} id="leftB" />

App.js I then in my App.js use this custom node, by creating it (handleClick method), and onConnect method to connect the edges and save them to this.state.initialEdges

Creates new node

handleClick() {
    const newNode = {
      id: `${this.state.initialNodes.length + 1}`,
      data: { label: this.state.inputText },
      type: "bidirectional",
      position: {
        x: 100,
        y: 100
      }
    };


this.setState(
      (prevState) => ({
        initialNodes: [...prevState.initialNodes, newNode],
        initialEdges: updatedEdges,
        inputText: "",
        reactFlowKey: prevState.reactFlowKey + 1
      }),

Creates Edges between the nodes

  const onConnect = (params) => {
      const { source, target, sourceHandleId, targetHandleId } = params;

      console.log("source:", source);
      console.log("target:", target);

      const newEdge1 = {
        id: `edge-${this.state.edgeCounter}`,
        source: source,
        target: target,
        type: "bidirectional",
        sourceHandle: sourceHandleId,
        targetHandle: targetHandleId
      };

      const newEdge2 = {
        id: `edge-${this.state.edgeCounter + 1}`,
        source: source,
        target: target,
        type: "bidirectional",
        sourceHandle: sourceHandleId,
        targetHandle: targetHandleId
      };

      this.setState((prevState) => ({
        initialEdges: addEdge(
          newEdge1,
          addEdge(newEdge2, prevState.initialEdges)
        ),
        edgeCounter: prevState.edgeCounter + 2
      }));
    };

console.log(newEdge1) after trying to connect the handles of the nodes

id: "edge-0"
source: "2"
target: "1"
type: "bidirectional"
sourceHandle: undefined
targetHandle: undefined

https://codesandbox.io/s/affectionate-liskov-dsfzcd?file=/src/App.js

Here's the link to the full code

I tried targeting the handle's unique id's, with getelement by id, targetHandleId, and I can't even remember how many more ways, I've asked copilot and gpt for help in many ways but they can't help.

The main problem I guess is that I created this whole code with state method (because thats the only way I know, I am learning react for a week now), while whole docs on their react-flow website is done in a different way (hooks?) without using this.state etc.

Also, I tried removing ReactFlowKey and replacing updating the website with something else, but nothing helped, and without ReactFlowKey, the nodes don't show up in html (they do in the console tho).


Solution

  • The solution that was helpful for me, was recreating the code with hooks, instead of forcibly using this.state for this library

    And chatgpt was able to recreate it more or less into hooks, after some basic debugging and readding button and input in other way, it seems to work perfectly.