ExamplesEdges

Temporary Edges

In React Flow, almost everything is built around the concepts of nodes and edges. Edges are the connections between nodes, but what if we want to create an edge that is only connected to one node? What about an “edge” not connected to any nodes at all?

This example shows how to create an “incomplete” edge when a user releases a connection line without making a connection. A ghost node is rendered where the connection line was released, and a temporary edge is added to the flow. Making use of editable edges, the user can pick the edge back up and complete the connection at which point the ghost node is removed!

Instead of connecting A directly to B in the flow, try releasing the connection line in an empty space to create a temporary edge!

import {
  Background,
  ReactFlow,
  ReactFlowProvider,
  useNodesState,
  useEdgesState,
} from '@xyflow/react';
 
import '@xyflow/react/dist/style.css';
 
 
import { GhostNode, useIncompleteEdge } from './useIncompleteEdge';
 
const nodeTypes = {
  ghost: GhostNode,
};
 
const initialNodes = [
  { id: '0', type: 'input', data: { label: 'A' }, position: { x: 0, y: -100 } },
  { id: '1', type: 'output', data: { label: 'B' }, position: { x: 0, y: 100 } },
];
 
const IncompleteEdge = () => {
  const [nodes, , onNodesChange] = useNodesState(initialNodes);
  const [edges, setEdges, onEdgesChange] = useEdgesState([]);
 
  const handlers = useIncompleteEdge();
 
  return (
    <ReactFlow
      nodes={nodes}
      nodeTypes={nodeTypes}
      edges={edges}
      onNodesChange={onNodesChange}
      onEdgesChange={onEdgesChange}
      fitView
      {...handlers}
      style={{ backgroundColor: "#F7F9FB" }}
      >
        <Background />
      </ReactFlow>  
  );
};
 
export default () => (
  <ReactFlowProvider>
    <IncompleteEdge />
  </ReactFlowProvider>
);

We’ve defined a useIncompleteEdge hook that encapsulates the logic for creating and managing a “ghost node”. It returns a number of event handlers intended to be passed to the <ReactFlow /> component.

  • onConnect is called when a complete connection is made.

  • onConnectEnd is called when the user releases a connection line. The seconed connectionState param can be used to determine if the connection was successful or not and where it started (and ended if the connection is valid). This callback creates a ghost node and a temporary edge from the connectionState.fromNode.id to that ghost node. The temporary edge is marked as reconnectable so that the user can pick it back up and complete the connection.

  • onReconnect is called when a complete reconnection is made.

  • onReconnectEnd is called when the user releases a reconnection line. This callback removes the ghost node and temporary edge. A new one may be added back when onConnectEnd is called.

This example is an adaptation of our add node on edge drop example!