refactor(store): use store.setState directly instead of actions

This commit is contained in:
moklick
2021-12-11 05:22:41 +01:00
parent 1a2ac5aa3e
commit 895e0bc524
14 changed files with 110 additions and 245 deletions
+4 -22
View File
@@ -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(
+21 -16
View File
@@ -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);
+8 -17
View File
@@ -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,
+6 -9
View File
@@ -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]
+30 -50
View File
@@ -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;
};
+8 -11
View File
@@ -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();
}, []);