refactor(store): use store.setState directly instead of actions
This commit is contained in:
@@ -10,9 +10,6 @@ import { getMarkerId } from '../../utils/graph';
|
||||
|
||||
const selector = (s: ReactFlowState) => ({
|
||||
addSelectedEdges: s.addSelectedEdges,
|
||||
setConnectionNodeId: s.setConnectionNodeId,
|
||||
setNodesSelectionActive: s.setNodesSelectionActive,
|
||||
setPosition: s.setConnectionPosition,
|
||||
connectionMode: s.connectionMode,
|
||||
});
|
||||
|
||||
@@ -57,10 +54,7 @@ export default (EdgeComponent: ComponentType<EdgeProps>) => {
|
||||
markerStart,
|
||||
}: WrapEdgeProps): JSX.Element | null => {
|
||||
const store = useStoreApi();
|
||||
const { addSelectedEdges, setConnectionNodeId, setNodesSelectionActive, setPosition, connectionMode } = useStore(
|
||||
selector,
|
||||
shallow
|
||||
);
|
||||
const { addSelectedEdges, connectionMode } = useStore(selector, shallow);
|
||||
|
||||
const [updating, setUpdating] = useState<boolean>(false);
|
||||
|
||||
@@ -99,7 +93,7 @@ export default (EdgeComponent: ComponentType<EdgeProps>) => {
|
||||
const onEdgeClick = useCallback(
|
||||
(event: React.MouseEvent<SVGGElement, MouseEvent>): void => {
|
||||
if (elementsSelectable) {
|
||||
setNodesSelectionActive(false);
|
||||
store.setState({ nodesSelectionActive: false });
|
||||
addSelectedEdges([edgeElement.id]);
|
||||
}
|
||||
|
||||
@@ -169,8 +163,7 @@ export default (EdgeComponent: ComponentType<EdgeProps>) => {
|
||||
event,
|
||||
handleId,
|
||||
nodeId,
|
||||
setConnectionNodeId,
|
||||
setPosition,
|
||||
store.setState,
|
||||
onConnectEdge,
|
||||
isTarget,
|
||||
isValidConnection,
|
||||
@@ -180,18 +173,7 @@ export default (EdgeComponent: ComponentType<EdgeProps>) => {
|
||||
store.getState
|
||||
);
|
||||
},
|
||||
[
|
||||
id,
|
||||
source,
|
||||
target,
|
||||
type,
|
||||
sourceHandleId,
|
||||
targetHandleId,
|
||||
setConnectionNodeId,
|
||||
setPosition,
|
||||
edgeElement,
|
||||
onEdgeUpdate,
|
||||
]
|
||||
[id, source, target, type, sourceHandleId, targetHandleId, edgeElement, onEdgeUpdate]
|
||||
);
|
||||
|
||||
const onEdgeUpdaterSourceMouseDown = useCallback(
|
||||
|
||||
@@ -1,23 +1,19 @@
|
||||
import { MouseEvent as ReactMouseEvent } from 'react';
|
||||
import { SetState } from 'zustand';
|
||||
|
||||
import { getHostForElement } from '../../utils';
|
||||
|
||||
import {
|
||||
OnConnect,
|
||||
OnConnectStart,
|
||||
OnConnectStop,
|
||||
OnConnectEnd,
|
||||
ConnectionMode,
|
||||
SetConnectionId,
|
||||
Connection,
|
||||
HandleType,
|
||||
XYPosition,
|
||||
ReactFlowState,
|
||||
} from '../../types';
|
||||
|
||||
type ValidConnectionFunc = (connection: Connection) => boolean;
|
||||
export type SetSourceIdFunc = (params: SetConnectionId) => void;
|
||||
|
||||
export type SetPosition = (pos: XYPosition) => void;
|
||||
|
||||
type Result = {
|
||||
elementBelow: Element | null;
|
||||
@@ -90,8 +86,7 @@ export function onMouseDown(
|
||||
event: ReactMouseEvent,
|
||||
handleId: string | null,
|
||||
nodeId: string,
|
||||
setConnectionNodeId: SetSourceIdFunc,
|
||||
setPosition: SetPosition,
|
||||
setState: SetState<ReactFlowState>,
|
||||
onConnect: OnConnect,
|
||||
isTarget: boolean,
|
||||
isValidConnection: ValidConnectionFunc,
|
||||
@@ -122,18 +117,24 @@ export function onMouseDown(
|
||||
const containerBounds = reactFlowNode.getBoundingClientRect();
|
||||
let recentHoveredHandle: Element;
|
||||
|
||||
setPosition({
|
||||
x: event.clientX - containerBounds.left,
|
||||
y: event.clientY - containerBounds.top,
|
||||
setState({
|
||||
connectionPosition: {
|
||||
x: event.clientX - containerBounds.left,
|
||||
y: event.clientY - containerBounds.top,
|
||||
},
|
||||
connectionNodeId: nodeId,
|
||||
connectionHandleId: handleId,
|
||||
connectionHandleType: handleType,
|
||||
});
|
||||
|
||||
setConnectionNodeId({ connectionNodeId: nodeId, connectionHandleId: handleId, connectionHandleType: handleType });
|
||||
onConnectStart?.(event, { nodeId, handleId, handleType });
|
||||
|
||||
function onMouseMove(event: MouseEvent) {
|
||||
setPosition({
|
||||
x: event.clientX - containerBounds.left,
|
||||
y: event.clientY - containerBounds.top,
|
||||
setState({
|
||||
connectionPosition: {
|
||||
x: event.clientX - containerBounds.left,
|
||||
y: event.clientY - containerBounds.top,
|
||||
},
|
||||
});
|
||||
|
||||
const { connection, elementBelow, isValid, isHoveringHandle } = checkElementBelowIsValid(
|
||||
@@ -183,7 +184,11 @@ export function onMouseDown(
|
||||
}
|
||||
|
||||
resetRecentHandle(recentHoveredHandle);
|
||||
setConnectionNodeId({ connectionNodeId: null, connectionHandleId: null, connectionHandleType: null });
|
||||
setState({
|
||||
connectionNodeId: null,
|
||||
connectionHandleId: null,
|
||||
connectionHandleType: null,
|
||||
});
|
||||
|
||||
doc.removeEventListener('mousemove', onMouseMove as EventListenerOrEventListenerObject);
|
||||
doc.removeEventListener('mouseup', onMouseUp as EventListenerOrEventListenerObject);
|
||||
|
||||
@@ -2,18 +2,16 @@ import React, { memo, useContext, useCallback, HTMLAttributes, forwardRef } from
|
||||
import cc from 'classcat';
|
||||
import shallow from 'zustand/shallow';
|
||||
|
||||
import { useStore } from '../../store';
|
||||
import { useStore, useStoreApi } from '../../store';
|
||||
import NodeIdContext from '../../contexts/NodeIdContext';
|
||||
import { HandleProps, Connection, ReactFlowState, Position } from '../../types';
|
||||
import { onMouseDown, SetSourceIdFunc, SetPosition } from './handler';
|
||||
import { onMouseDown } from './handler';
|
||||
|
||||
const alwaysValid = () => true;
|
||||
|
||||
export type HandleComponentProps = HandleProps & Omit<HTMLAttributes<HTMLDivElement>, 'id'>;
|
||||
|
||||
const selector = (s: ReactFlowState) => ({
|
||||
setPosition: s.setConnectionPosition,
|
||||
setConnectionNodeId: s.setConnectionNodeId,
|
||||
onConnectAction: s.onConnect,
|
||||
onConnectStart: s.onConnectStart,
|
||||
onConnectStop: s.onConnectStop,
|
||||
@@ -36,16 +34,12 @@ const Handle = forwardRef<HTMLDivElement, HandleComponentProps>(
|
||||
},
|
||||
ref
|
||||
) => {
|
||||
const store = useStoreApi();
|
||||
const nodeId = useContext(NodeIdContext) as string;
|
||||
const {
|
||||
setPosition,
|
||||
setConnectionNodeId,
|
||||
onConnectAction,
|
||||
onConnectStart,
|
||||
onConnectStop,
|
||||
onConnectEnd,
|
||||
connectionMode,
|
||||
} = useStore(selector, shallow);
|
||||
const { onConnectAction, onConnectStart, onConnectStop, onConnectEnd, connectionMode } = useStore(
|
||||
selector,
|
||||
shallow
|
||||
);
|
||||
|
||||
const handleId = id || null;
|
||||
const isTarget = type === 'target';
|
||||
@@ -64,8 +58,7 @@ const Handle = forwardRef<HTMLDivElement, HandleComponentProps>(
|
||||
event,
|
||||
handleId,
|
||||
nodeId,
|
||||
setConnectionNodeId as unknown as SetSourceIdFunc,
|
||||
setPosition as unknown as SetPosition,
|
||||
store.setState,
|
||||
onConnectExtended,
|
||||
isTarget,
|
||||
isValidConnection,
|
||||
@@ -80,8 +73,6 @@ const Handle = forwardRef<HTMLDivElement, HandleComponentProps>(
|
||||
[
|
||||
handleId,
|
||||
nodeId,
|
||||
setConnectionNodeId,
|
||||
setPosition,
|
||||
onConnectExtended,
|
||||
isTarget,
|
||||
isValidConnection,
|
||||
|
||||
@@ -3,13 +3,12 @@ import { DraggableCore, DraggableData, DraggableEvent } from 'react-draggable';
|
||||
import cc from 'classcat';
|
||||
import shallow from 'zustand/shallow';
|
||||
|
||||
import { useStore } from '../../store';
|
||||
import { useStore, useStoreApi } from '../../store';
|
||||
import { Provider } from '../../contexts/NodeIdContext';
|
||||
import { NodeProps, WrapNodeProps, ReactFlowState } from '../../types';
|
||||
|
||||
const selector = (s: ReactFlowState) => ({
|
||||
addSelectedNodes: s.addSelectedNodes,
|
||||
setNodesSelectionActive: s.setNodesSelectionActive,
|
||||
updateNodePosition: s.updateNodePosition,
|
||||
unselectNodesAndEdges: s.unselectNodesAndEdges,
|
||||
});
|
||||
@@ -52,10 +51,8 @@ export default (NodeComponent: ComponentType<NodeProps>) => {
|
||||
noPanClassName,
|
||||
noDragClassName,
|
||||
}: WrapNodeProps) => {
|
||||
const { addSelectedNodes, unselectNodesAndEdges, setNodesSelectionActive, updateNodePosition } = useStore(
|
||||
selector,
|
||||
shallow
|
||||
);
|
||||
const store = useStoreApi();
|
||||
const { addSelectedNodes, unselectNodesAndEdges, updateNodePosition } = useStore(selector, shallow);
|
||||
const nodeElement = useRef<HTMLDivElement>(null);
|
||||
const hasPointerEvents = isSelectable || isDraggable || onClick || onMouseEnter || onMouseMove || onMouseLeave;
|
||||
const nodeStyle: CSSProperties = useMemo(
|
||||
@@ -109,7 +106,7 @@ export default (NodeComponent: ComponentType<NodeProps>) => {
|
||||
(event: MouseEvent) => {
|
||||
if (!isDraggable) {
|
||||
if (isSelectable) {
|
||||
setNodesSelectionActive(false);
|
||||
store.setState({ nodesSelectionActive: false });
|
||||
|
||||
if (!selected) {
|
||||
addSelectedNodes([node.id]);
|
||||
@@ -127,14 +124,14 @@ export default (NodeComponent: ComponentType<NodeProps>) => {
|
||||
onNodeDragStart?.(event as MouseEvent, node);
|
||||
|
||||
if (selectNodesOnDrag && isSelectable) {
|
||||
setNodesSelectionActive(false);
|
||||
store.setState({ nodesSelectionActive: false });
|
||||
|
||||
if (!selected) {
|
||||
addSelectedNodes([node.id]);
|
||||
}
|
||||
} else if (!selectNodesOnDrag && !selected && isSelectable) {
|
||||
unselectNodesAndEdges();
|
||||
setNodesSelectionActive(false);
|
||||
store.setState({ nodesSelectionActive: false });
|
||||
}
|
||||
},
|
||||
[node, selected, selectNodesOnDrag, isSelectable, onNodeDragStart]
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { useEffect } from 'react';
|
||||
import { SetState } from 'zustand';
|
||||
import shallow from 'zustand/shallow';
|
||||
|
||||
import { useStore } from '../../store';
|
||||
import { useStore, useStoreApi } from '../../store';
|
||||
import {
|
||||
Node,
|
||||
Edge,
|
||||
@@ -42,24 +43,11 @@ interface StoreUpdaterProps {
|
||||
const selector = (s: ReactFlowState) => ({
|
||||
setNodes: s.setNodes,
|
||||
setEdges: s.setEdges,
|
||||
setOnConnect: s.setOnConnect,
|
||||
setOnConnectStart: s.setOnConnectStart,
|
||||
setOnConnectStop: s.setOnConnectStop,
|
||||
setOnConnectEnd: s.setOnConnectEnd,
|
||||
setSnapGrid: s.setSnapGrid,
|
||||
setSnapToGrid: s.setSnapToGrid,
|
||||
setNodesDraggable: s.setNodesDraggable,
|
||||
setNodesConnectable: s.setNodesConnectable,
|
||||
setElementsSelectable: s.setElementsSelectable,
|
||||
setMinZoom: s.setMinZoom,
|
||||
setMaxZoom: s.setMaxZoom,
|
||||
setTranslateExtent: s.setTranslateExtent,
|
||||
setNodeExtent: s.setNodeExtent,
|
||||
setConnectionMode: s.setConnectionMode,
|
||||
setOnNodesChange: s.setOnNodesChange,
|
||||
setOnEdgesChange: s.setOnEdgesChange,
|
||||
reset: s.reset,
|
||||
setFitViewOnInit: s.setFitViewOnInit,
|
||||
});
|
||||
|
||||
function useStoreUpdater<T>(value: T | undefined, setStoreState: (param: T) => void) {
|
||||
@@ -70,6 +58,15 @@ function useStoreUpdater<T>(value: T | undefined, setStoreState: (param: T) => v
|
||||
}, [value]);
|
||||
}
|
||||
|
||||
function useDirectStoreUpdater(key: keyof ReactFlowState, value: any, setState: SetState<ReactFlowState>) {
|
||||
useEffect(() => {
|
||||
if (typeof value !== 'undefined') {
|
||||
// @ts-ignore
|
||||
setState({ [key]: value });
|
||||
}
|
||||
}, [value]);
|
||||
}
|
||||
|
||||
const StoreUpdater = ({
|
||||
nodes,
|
||||
edges,
|
||||
@@ -91,28 +88,11 @@ const StoreUpdater = ({
|
||||
translateExtent,
|
||||
fitViewOnInit,
|
||||
}: StoreUpdaterProps) => {
|
||||
const {
|
||||
setNodes,
|
||||
setEdges,
|
||||
setOnConnect,
|
||||
setOnConnectStart,
|
||||
setOnConnectStop,
|
||||
setOnConnectEnd,
|
||||
setNodesDraggable,
|
||||
setSnapGrid,
|
||||
setSnapToGrid,
|
||||
setNodesConnectable,
|
||||
setElementsSelectable,
|
||||
setMinZoom,
|
||||
setMaxZoom,
|
||||
setTranslateExtent,
|
||||
setNodeExtent,
|
||||
setOnNodesChange,
|
||||
setOnEdgesChange,
|
||||
setConnectionMode,
|
||||
reset,
|
||||
setFitViewOnInit,
|
||||
} = useStore(selector, shallow);
|
||||
const { setNodes, setEdges, setMinZoom, setMaxZoom, setTranslateExtent, setNodeExtent, reset } = useStore(
|
||||
selector,
|
||||
shallow
|
||||
);
|
||||
const store = useStoreApi();
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
@@ -122,24 +102,24 @@ const StoreUpdater = ({
|
||||
|
||||
useStoreUpdater<Node[]>(nodes, setNodes);
|
||||
useStoreUpdater<Edge[]>(edges, setEdges);
|
||||
useStoreUpdater<OnConnect>(onConnect, setOnConnect);
|
||||
useStoreUpdater<OnConnect>(onConnect, setOnConnect);
|
||||
useStoreUpdater<OnConnectStart>(onConnectStart, setOnConnectStart);
|
||||
useStoreUpdater<OnConnectStop>(onConnectStop, setOnConnectStop);
|
||||
useStoreUpdater<OnConnectEnd>(onConnectEnd, setOnConnectEnd);
|
||||
useStoreUpdater<boolean>(snapToGrid, setSnapToGrid);
|
||||
useStoreUpdater<SnapGrid>(snapGrid, setSnapGrid);
|
||||
useStoreUpdater<boolean>(nodesDraggable, setNodesDraggable);
|
||||
useStoreUpdater<boolean>(nodesConnectable, setNodesConnectable);
|
||||
useStoreUpdater<boolean>(elementsSelectable, setElementsSelectable);
|
||||
useStoreUpdater<number>(minZoom, setMinZoom);
|
||||
useStoreUpdater<number>(maxZoom, setMaxZoom);
|
||||
useStoreUpdater<CoordinateExtent>(translateExtent, setTranslateExtent);
|
||||
useStoreUpdater<CoordinateExtent>(nodeExtent, setNodeExtent);
|
||||
useStoreUpdater<ConnectionMode>(connectionMode, setConnectionMode);
|
||||
useStoreUpdater<OnNodesChange>(onNodesChange, setOnNodesChange);
|
||||
useStoreUpdater<OnEdgesChange>(onEdgesChange, setOnEdgesChange);
|
||||
useStoreUpdater<boolean>(fitViewOnInit, setFitViewOnInit);
|
||||
|
||||
useDirectStoreUpdater('connectionMode', connectionMode, store.setState);
|
||||
useDirectStoreUpdater('onConnect', onConnect, store.setState);
|
||||
useDirectStoreUpdater('onConnectStart', onConnectStart, store.setState);
|
||||
useDirectStoreUpdater('onConnectStop', onConnectStop, store.setState);
|
||||
useDirectStoreUpdater('onConnectEnd', onConnectEnd, store.setState);
|
||||
useDirectStoreUpdater('nodesDraggable', nodesDraggable, store.setState);
|
||||
useDirectStoreUpdater('nodesConnectable', nodesConnectable, store.setState);
|
||||
useDirectStoreUpdater('elementsSelectable', elementsSelectable, store.setState);
|
||||
useDirectStoreUpdater('fitViewOnInit', fitViewOnInit, store.setState);
|
||||
useDirectStoreUpdater('snapToGrid', snapToGrid, store.setState);
|
||||
useDirectStoreUpdater('snapGrid', snapGrid, store.setState);
|
||||
useDirectStoreUpdater('onNodesChange', onNodesChange, store.setState);
|
||||
useDirectStoreUpdater('onEdgesChange', onEdgesChange, store.setState);
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
@@ -30,8 +30,6 @@ function getMousePosition(event: React.MouseEvent, containerBounds: DOMRect): XY
|
||||
const selector = (s: ReactFlowState) => ({
|
||||
userSelectionActive: s.userSelectionActive,
|
||||
elementsSelectable: s.elementsSelectable,
|
||||
setUserSelectionActive: s.setUserSelectionActive,
|
||||
setNodesSelectionActive: s.setNodesSelectionActive,
|
||||
});
|
||||
|
||||
const initialRect: SelectionRect = {
|
||||
@@ -50,16 +48,14 @@ export default memo(({ selectionKeyPressed }: UserSelectionProps) => {
|
||||
const prevSelectedEdgesCount = useRef<number>(0);
|
||||
const containerBounds = useRef<DOMRect>();
|
||||
const [userSelectionRect, setUserSelectionRect] = useState<SelectionRect>(initialRect);
|
||||
const { userSelectionActive, elementsSelectable, setUserSelectionActive, setNodesSelectionActive } = useStore(
|
||||
selector,
|
||||
shallow
|
||||
);
|
||||
const { userSelectionActive, elementsSelectable } = useStore(selector, shallow);
|
||||
|
||||
const renderUserSelectionPane = userSelectionActive || selectionKeyPressed;
|
||||
|
||||
const resetUserSelection = useCallback(() => {
|
||||
setUserSelectionRect(initialRect);
|
||||
setUserSelectionActive(false);
|
||||
|
||||
store.setState({ userSelectionActive: false });
|
||||
|
||||
prevSelectedNodesCount.current = 0;
|
||||
prevSelectedEdgesCount.current = 0;
|
||||
@@ -81,8 +77,7 @@ export default memo(({ selectionKeyPressed }: UserSelectionProps) => {
|
||||
draw: true,
|
||||
});
|
||||
|
||||
setUserSelectionActive(true);
|
||||
setNodesSelectionActive(false);
|
||||
store.setState({ userSelectionActive: true, nodesSelectionActive: false });
|
||||
}, []);
|
||||
|
||||
const onMouseMove = (event: React.MouseEvent): void => {
|
||||
@@ -128,12 +123,14 @@ export default memo(({ selectionKeyPressed }: UserSelectionProps) => {
|
||||
};
|
||||
|
||||
const onMouseUp = useCallback(() => {
|
||||
setNodesSelectionActive(prevSelectedNodesCount.current > 0);
|
||||
store.setState({ nodesSelectionActive: prevSelectedNodesCount.current > 0 });
|
||||
|
||||
resetUserSelection();
|
||||
}, []);
|
||||
|
||||
const onMouseLeave = useCallback(() => {
|
||||
setNodesSelectionActive(false);
|
||||
store.setState({ nodesSelectionActive: false });
|
||||
|
||||
resetUserSelection();
|
||||
}, []);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user