fix(selection-change): only trigger once

This commit is contained in:
moklick
2022-02-22 17:49:10 +01:00
parent 007bdabb89
commit 67b71a9190
2 changed files with 19 additions and 10 deletions
+18 -9
View File
@@ -1,29 +1,38 @@
import { useEffect } from 'react'; import { memo, useEffect } from 'react';
import shallow from 'zustand/shallow'; import shallow from 'zustand/shallow';
import { ReactFlowState, OnSelectionChangeFunc } from '../../types'; import { ReactFlowState, OnSelectionChangeFunc, Node, Edge } from '../../types';
import { useStore } from '../../store'; import { useStore } from '../../store';
interface SelectionListenerProps { interface SelectionListenerProps {
onSelectionChange: OnSelectionChangeFunc; onSelectionChange: OnSelectionChangeFunc;
} }
// @TODO: work with nodeInternals instead of converting it to an array
const selector = (s: ReactFlowState) => ({ const selector = (s: ReactFlowState) => ({
selectedNodes: Array.from(s.nodeInternals) selectedNodes: Array.from(s.nodeInternals.values()).filter((n) => n.selected),
.filter(([_, n]) => n.selected)
.map(([_, node]) => node),
selectedEdges: s.edges.filter((e) => e.selected), selectedEdges: s.edges.filter((e) => e.selected),
}); });
const areEqual = (objA: any, objB: any) => {
const selectedNodeIdsA = objA.selectedNodes.map((n: Node) => n.id);
const selectedNodeIdsB = objB.selectedNodes.map((n: Node) => n.id);
const selectedEdgeIdsA = objA.selectedEdges.map((e: Edge) => e.id);
const selectedEdgeIdsB = objB.selectedEdges.map((e: Edge) => e.id);
return shallow(selectedNodeIdsA, selectedNodeIdsB) && shallow(selectedEdgeIdsA, selectedEdgeIdsB);
};
// This is just a helper component for calling the onSelectionChange listener. // This is just a helper component for calling the onSelectionChange listener.
// @TODO: Now that we have the onNodesChange and on EdgesChange listeners, do we still need this component? // @TODO: Now that we have the onNodesChange and on EdgesChange listeners, do we still need this component?
export default ({ onSelectionChange }: SelectionListenerProps) => { function SelectionListener({ onSelectionChange }: SelectionListenerProps) {
const { selectedNodes, selectedEdges } = useStore(selector, shallow); const { selectedNodes, selectedEdges } = useStore(selector, areEqual);
useEffect(() => { useEffect(() => {
onSelectionChange({ nodes: selectedNodes, edges: selectedEdges }); onSelectionChange({ nodes: selectedNodes, edges: selectedEdges });
}, [selectedNodes, selectedEdges]); }, [selectedNodes, selectedEdges]);
return null; return null;
}; }
export default memo(SelectionListener);
+1 -1
View File
@@ -22,7 +22,7 @@ export type OnEdgesChange = (nodes: EdgeChange[]) => void;
export type OnNodesDelete = (nodes: Node[]) => void; export type OnNodesDelete = (nodes: Node[]) => void;
export type OnEdgesDelete = (edges: Edge[]) => void; export type OnEdgesDelete = (edges: Edge[]) => void;
export type OnMove = (event: MouseEvent | TouchEvent, viweport: Viewport) => void; export type OnMove = (event: MouseEvent | TouchEvent, viewport: Viewport) => void;
export type OnMoveStart = OnMove; export type OnMoveStart = OnMove;
export type OnMoveEnd = OnMove; export type OnMoveEnd = OnMove;