React Flow Code Review
v1.1.0Reviews React Flow code for anti-patterns, performance issues, and best practices. Use when reviewing code that uses @xyflow/react, checking for common mista...
详细分析 ▾
运行时依赖
版本
- Added comprehensive best practices guide for reviewing React Flow code, focusing on anti-patterns, performance, and common mistakes. - Lists critical anti-patterns such as improper memoization, callback usage, and misuse of providers. - Includes checklists for node/edge rendering, state updates, and viewport handling. - Addresses common integration errors like missing container height, required CSS, and proper event handling. - Highlights TypeScript tips for improved type safety with custom nodes and components. - Provides review questions to ensure code quality and consistency.
安装命令 点击复制
技能文档
Critical Anti-Patterns
1. Defining nodeTypes/edgeTypes Inside Components
Problem: Causes all nodes to re-mount on every render.
// BAD - recreates object every render
function Flow() {
const nodeTypes = { custom: CustomNode }; // WRONG
return ;
}// GOOD - defined outside component
const nodeTypes = { custom: CustomNode };
function Flow() {
return ;
}
// GOOD - useMemo if dynamic
function Flow() {
const nodeTypes = useMemo(() => ({ custom: CustomNode }), []);
return ;
}
2. Missing memo() on Custom Nodes/Edges
Problem: Custom components re-render on every parent update.
// BAD - no memoization
function CustomNode({ data }: NodeProps) {
return {data.label};
}// GOOD - wrapped in memo
import { memo } from 'react';
const CustomNode = memo(function CustomNode({ data }: NodeProps) {
return
{data.label};
});
3. Inline Callbacks Without useCallback
Problem: Creates new function references, breaking memoization.
// BAD - inline callback
setNodes(applyNodeChanges(changes, nodes))}
/>// GOOD - memoized callback
const onNodesChange = useCallback(
(changes) => setNodes((nds) => applyNodeChanges(changes, nds)),
[]
);
4. Using useReactFlow Outside Provider
// BAD - will throw error
function App() {
const { getNodes } = useReactFlow(); // ERROR: No provider
return ;
}// GOOD - wrap in provider
function FlowContent() {
const { getNodes } = useReactFlow(); // Works
return ;
}
function App() {
return (
);
}
5. Storing Complex Objects in Node Data
Problem: Reference equality checks fail, causing unnecessary updates.
// BAD - new object reference every time
setNodes(nodes.map(n => ({
...n,
data: { ...n.data, config: { nested: 'value' } } // New object each time
})));// GOOD - use updateNodeData for targeted updates
const { updateNodeData } = useReactFlow();
updateNodeData(nodeId, { config: { nested: 'value' } });
Performance Checklist
Node Rendering
- [ ] Custom nodes wrapped in
memo() - [ ] nodeTypes defined outside component or memoized
- [ ] Heavy computations inside nodes use
useMemo - [ ] Event handlers use
useCallback
Edge Rendering
- [ ] Custom edges wrapped in
memo() - [ ] edgeTypes defined outside component or memoized
- [ ] Edge path calculations are not duplicated
State Updates
- [ ] Using functional form of setState:
setNodes((nds) => ...) - [ ] Not spreading entire state for single property updates
- [ ] Using
updateNodeDatafor data-only changes - [ ] Batch updates when adding multiple nodes/edges
Viewport
- [ ] Not calling
fitView()on every render - [ ] Using
fitViewOptionsfor initial fit only - [ ] Animation durations are reasonable (< 500ms)
Common Mistakes
Missing Container Height
// BAD - no height, flow won't render
// GOOD - explicit dimensions
Missing CSS Import
// Required for default styles
import '@xyflow/react/dist/style.css';
Forgetting nodrag on Interactive Elements
// BAD - clicking button drags node
// GOOD - prevents drag
Not Using Position Constants
// BAD - string literals
// GOOD - type-safe constants
import { Position } from '@xyflow/react';
Mutating Nodes/Edges Directly
// BAD - direct mutation
nodes[0].position = { x: 100, y: 100 };
setNodes(nodes);// GOOD - immutable update
setNodes(nodes.map(n =>
n.id === '1' ? { ...n, position: { x: 100, y: 100 } } : n
));
TypeScript Issues
Missing Generic Types
// BAD - loses type safety
const [nodes, setNodes] = useNodesState(initialNodes);// GOOD - explicit types
type MyNode = Node<{ value: number }, 'custom'>;
const [nodes, setNodes] = useNodesState(initialNodes);
Wrong Props Type
// BAD - using wrong type
function CustomNode(props: any) { ... }// GOOD - correct props type
function CustomNode(props: NodeProps) { ... }
Review Questions
- Are all custom components memoized?
- Are nodeTypes/edgeTypes defined outside render?
- Are callbacks wrapped in useCallback?
- Is the container sized properly?
- Are styles imported?
- Is useReactFlow used inside a provider?
- Are interactive elements marked with nodrag?
- Are types used consistently throughout?
免费技能或插件可能存在安全风险,如需更匹配、更安全的方案,建议联系付费定制