React Flow: Prevent onSelectionChange from Triggering on Node Click and Drag
Issue
I'm using React Flow (XYFlow) to implement a selection box that, when released, fits the view to the selected nodes. However, event handlers are clashing:
- onNodeClick and onSelectionChange trigger simultaneously when clicking a node.
- onSelectionChange is also triggered when dragging a node.
- onSelectionEnd fires when clicking outside the selection box, zooming into previously selected node.
Desired Behavior
- onNodeClick should only handle node clicks.
- onSelectionChange should only handle selection box updates.
- onSelectionEnd should trigger only when a selection box is explicitly created and released.
Current Implementation
const onSelectionChange = (params:{nodes: Node[]; edges:Edge[];}) => {
console.log("Change: ", params, selectedNodeIds);
if (params.nodes.length>0){
const selectedIds = params.nodes
.map((node: { id: string; }) => node.id);
setSelectedNodeIds(selectedIds);
}
}
const onSelectionEnd = (event:any)=>{
console.log("Selection End", event);
if (selectedNodeIds.length > 0){
const selectedNodes = selectedNodeIds
.map((id) => reactFlowInstance?.getNode(id))
.filter((node) => node !== undefined);
if (selectedNodes.length === 0) return;
reactFlowInstance?.fitView({
nodes:selectedNodes,
duration:1000,
}).then(() => {
setSelectedNodeIds([]);
}).catch((error)=>{
console.error("There was an error: ", error)
})
}
}
const onNodeClick = (event: React.MouseEvent, node:Node) =>{
console.log("Node clicked!?")
// other logic
}
<ReactFlowProvider>
<ReactFlow
onSelectionChange={onSelectionChange}
onSelectionEnd={onSelectionEnd}
onNodeClick={onNodeClick}
/>
</ReactFlowProvider>
Concised Question
How can I prevent onSelectionChange from triggering on node clicks and drags, while ensuring onSelectionEnd only fires for actual selection box usage? Are there better event handlers or patterns to use in React Flow?
I tried to check logic faults from my end. I tried to order the event handler in with onNodeClick followed by onSelectionChange. which failed obviously.