How to Create a Draggable Node When Click on a Button in React Flow - Typescript?

How to Create a Draggable Node When Click on a Button in React Flow - Typescript?

i am working on react flow using typescript, for react flow i am using ractflow and react-flow-renderer packages. In the start i have one node and a button, what i want is: when i click on the button => create a new node. i was able to create a new node when i click on the button, but my problem is: i can not drag my nodes or join them together: this is my code:

/* -------------------------------------------------------------------------- */
/*                                  Libraries                                 */
/* -------------------------------------------------------------------------- */
import React, { useCallback, useState, useRef } from "react";
import ReactFlow from "react-flow-renderer";

/* -------------------------------------------------------------------------- */
/*                               Implementation                               */
/* -------------------------------------------------------------------------- */
const initialElements = [
  {
    id: "1",
    type: "input",
    data: { label: "Input Node" },
    position: { x: 100, y: 0 },
  },
];

/* -------------------------------------------------------------------------- */
/*                                  Function                                  */
/* -------------------------------------------------------------------------- */
export default function Flow() {
  const [els, setEls] = useState(initialElements);
  const yPos = useRef(0);

  const addNode = useCallback(() => {
    yPos.current += 80;
    setEls((els: any) => {
      console.log(els);
      return [
        ...els,
        {
          id: Math.random(),
          position: { x: 100, y: yPos.current },
          data: { label: "new node" },
          style: {
            backgroundColor: "#00fff0",
            visibility: "visible",
          },
        },
      ];
    });
  }, []);

  const addEdge = useCallback(({ source, target }: any) => {
    setEls((els: any) => {
      console.log(source, target);
      return [
        ...els,
        {
          id: Math.random(),
          source,
          target,
        },
      ];
    });
  }, []);

  return (
    <div>
      {/* React Flow */}
      <div style={{ height: 300 }}>
        <ReactFlow nodes={els} nodesDraggable={true} nodesConnectable={true} />
      </div>

      {/* if this button will be clicked a new node should be created */}
      <button onClick={addNode} className="p-2 m-2 rounded-md bg-[#00fff0]">
        Add
      </button>
    </div>
  );
}

and this is what i got so far:

anyone can help how i can make the nodes draggable and able to join them together? Thanx in advance

1 Answer

Your code does not apply drag events to your state (els). Refer to

Basically, you're missing change handler:

import ReactFlow, { applyNodeChanges } from 'reactflow';

...

  const onNodesChange = useCallback(
    (changes) => setEls((els) => applyNodeChanges(changes, els)),
    []
  );

  <ReactFlow nodes={els} onNodesChange={onNodesChange} ... />

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Chloe Bennett
Author

Chloe Bennett

Chloe Bennett explores the intersection of pop culture, streaming entertainment, digital trends, and contemporary lifestyle. Her weekly commentary reaches thousands of culture enthusiasts.