Comprehensive React Flow (@xyflow/react) patterns and best practices for building node-based UIs, workflow editors, and interactive diagrams. Use when working with React Flow for (1) building flow editors or node-based interfaces, (2) creating custom nodes and edges, (3) implementing drag-and-drop workflows, (4) optimizing performance for large graphs, (5) managing flow state and interactions, (6) implementing auto-layout or positioning, or (7) TypeScript integration with React Flow.
95
95%
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Passed
No known issues
Always wrap custom node and edge components with React.memo() to prevent unnecessary re-renders when other parts of the graph change.
Incorrect (no memoization):
// ❌ Re-renders on every graph update (any node/edge change)
function CustomNode({ data, selected }) {
return (
<div className={`node ${selected ? 'selected' : ''}`}>
<Handle type="target" position={Position.Top} />
<div>{data.label}</div>
<Handle type="source" position={Position.Bottom} />
</div>
);
}
// With 100 nodes, a single node update triggers 100 re-renders!Correct (memoized):
import { memo } from 'react';
import { Handle, Position, NodeProps } from '@xyflow/react';
// ✅ Only re-renders when this specific node's props change
const CustomNode = memo(({ data, selected }: NodeProps) => {
return (
<div className={`node ${selected ? 'selected' : ''}`}>
<Handle type="target" position={Position.Top} />
<div>{data.label}</div>
<Handle type="source" position={Position.Bottom} />
</div>
);
});
CustomNode.displayName = 'CustomNode'; // Helpful for debuggingFor Custom Edges:
import { memo } from 'react';
import { BaseEdge, getBezierPath, EdgeProps } from '@xyflow/react';
const CustomEdge = memo(({ id, sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition }: EdgeProps) => {
const [edgePath] = getBezierPath({
sourceX,
sourceY,
sourcePosition,
targetX,
targetY,
targetPosition,
});
return <BaseEdge path={edgePath} />;
});
CustomEdge.displayName = 'CustomEdge';Performance Impact:
Without memoization:
With memoization:
Additional Tips:
React.memo() for all custom components (nodes, edges, connection lines)Reference: Performance Best Practices