refactor(state): replace redux with zustand

This commit is contained in:
moklick
2021-10-13 12:54:01 +02:00
parent e01249a87c
commit ee0d29029a
38 changed files with 786 additions and 896 deletions
+29 -12
View File
@@ -1,6 +1,6 @@
import React, { memo, CSSProperties, useCallback } from 'react';
import { useStoreState } from '../../store/hooks';
import { useStore } from '../../store';
import ConnectionLine from '../../components/ConnectionLine/index';
import { isEdge } from '../../utils/graph';
import MarkerDefinitions from './MarkerDefinitions';
@@ -15,6 +15,7 @@ import {
ConnectionLineComponent,
ConnectionMode,
OnEdgeUpdateFunc,
ReactFlowState,
} from '../../types';
interface EdgeRendererProps {
@@ -199,18 +200,34 @@ const Edge = memo(
}
);
const selector = (s: ReactFlowState) => ({
transform: s.transform,
edges: s.edges,
connectionNodeId: s.connectionNodeId,
connectionHandleId: s.connectionHandleId,
connectionHandleType: s.connectionHandleType,
connectionPosition: s.connectionPosition,
selectedElements: s.selectedElements,
nodesConnectable: s.nodesConnectable,
elementsSelectable: s.elementsSelectable,
width: s.width,
height: s.height,
});
const EdgeRenderer = (props: EdgeRendererProps) => {
const transform = useStoreState((state) => state.transform);
const edges = useStoreState((state) => state.edges);
const connectionNodeId = useStoreState((state) => state.connectionNodeId);
const connectionHandleId = useStoreState((state) => state.connectionHandleId);
const connectionHandleType = useStoreState((state) => state.connectionHandleType);
const connectionPosition = useStoreState((state) => state.connectionPosition);
const selectedElements = useStoreState((state) => state.selectedElements);
const nodesConnectable = useStoreState((state) => state.nodesConnectable);
const elementsSelectable = useStoreState((state) => state.elementsSelectable);
const width = useStoreState((state) => state.width);
const height = useStoreState((state) => state.height);
const {
transform,
edges,
connectionNodeId,
connectionHandleId,
connectionHandleType,
connectionPosition,
selectedElements,
nodesConnectable,
elementsSelectable,
width,
height,
} = useStore(selector);
if (!width) {
return null;
+9 -5
View File
@@ -1,13 +1,13 @@
import React, { useCallback, memo, ReactNode, WheelEvent, MouseEvent } from 'react';
import { useStoreActions, useStoreState } from '../../store/hooks';
import { useStore } from '../../store';
import useGlobalKeyHandler from '../../hooks/useGlobalKeyHandler';
import useKeyPress from '../../hooks/useKeyPress';
import { GraphViewProps } from '../GraphView';
import ZoomPane from '../ZoomPane';
import UserSelection from '../../components/UserSelection';
import NodesSelection from '../../components/NodesSelection';
import { ReactFlowState } from '../../types';
interface FlowRendererProps
extends Omit<
@@ -25,6 +25,12 @@ interface FlowRendererProps
children: ReactNode;
}
const selector = (s: ReactFlowState) => ({
unsetNodesSelection: s.unsetNodesSelection,
resetSelectedElements: s.resetSelectedElements,
nodesSelectionActive: s.nodesSelectionActive,
});
const FlowRenderer = ({
children,
onPaneClick,
@@ -54,9 +60,7 @@ const FlowRenderer = ({
onSelectionDragStop,
onSelectionContextMenu,
}: FlowRendererProps) => {
const unsetNodesSelection = useStoreActions((actions) => actions.unsetNodesSelection);
const resetSelectedElements = useStoreActions((actions) => actions.resetSelectedElements);
const nodesSelectionActive = useStoreState((state) => state.nodesSelectionActive);
const { unsetNodesSelection, resetSelectedElements, nodesSelectionActive } = useStore(selector);
const selectionKeyPressed = useKeyPress(selectionKeyCode);
+21 -21
View File
@@ -1,6 +1,6 @@
import React, { useEffect, useRef, memo } from 'react';
import { useStoreActions, useStore } from '../../store/hooks';
import { useStore, useStoreApi } from '../../store';
import FlowRenderer from '../FlowRenderer';
import NodeRenderer from '../NodeRenderer';
import EdgeRenderer from '../EdgeRenderer';
@@ -98,24 +98,24 @@ const GraphView = ({
onEdgesChange,
}: GraphViewProps) => {
const isInitialized = useRef<boolean>(false);
const setOnConnect = useStoreActions((actions) => actions.setOnConnect);
const setOnConnectStart = useStoreActions((actions) => actions.setOnConnectStart);
const setOnConnectStop = useStoreActions((actions) => actions.setOnConnectStop);
const setOnConnectEnd = useStoreActions((actions) => actions.setOnConnectEnd);
const setSnapGrid = useStoreActions((actions) => actions.setSnapGrid);
const setSnapToGrid = useStoreActions((actions) => actions.setSnapToGrid);
const setNodesDraggable = useStoreActions((actions) => actions.setNodesDraggable);
const setNodesConnectable = useStoreActions((actions) => actions.setNodesConnectable);
const setElementsSelectable = useStoreActions((actions) => actions.setElementsSelectable);
const setMinZoom = useStoreActions((actions) => actions.setMinZoom);
const setMaxZoom = useStoreActions((actions) => actions.setMaxZoom);
const setTranslateExtent = useStoreActions((actions) => actions.setTranslateExtent);
const setNodeExtent = useStoreActions((actions) => actions.setNodeExtent);
const setConnectionMode = useStoreActions((actions) => actions.setConnectionMode);
const setOnNodesChange = useStoreActions((actions) => actions.setOnNodesChange);
const setOnEdgesChange = useStoreActions((actions) => actions.setOnEdgesChange);
const store = useStoreApi();
const setOnConnect = useStore((s) => s.setOnConnect);
const setOnConnectStart = useStore((s) => s.setOnConnectStart);
const setOnConnectStop = useStore((s) => s.setOnConnectStop);
const setOnConnectEnd = useStore((s) => s.setOnConnectEnd);
const setSnapGrid = useStore((s) => s.setSnapGrid);
const setSnapToGrid = useStore((s) => s.setSnapToGrid);
const setNodesDraggable = useStore((s) => s.setNodesDraggable);
const setNodesConnectable = useStore((s) => s.setNodesConnectable);
const setElementsSelectable = useStore((s) => s.setElementsSelectable);
const setMinZoom = useStore((s) => s.setMinZoom);
const setMaxZoom = useStore((s) => s.setMaxZoom);
const setTranslateExtent = useStore((s) => s.setTranslateExtent);
const setNodeExtent = useStore((s) => s.setNodeExtent);
const setConnectionMode = useStore((s) => s.setConnectionMode);
const setOnNodesChange = useStore((s) => s.setOnNodesChange);
const setOnEdgesChange = useStore((s) => s.setOnEdgesChange);
const currentStore = useStore();
const { zoomIn, zoomOut, zoomTo, transform, fitView, initialized } = useZoomPanHelper();
useEffect(() => {
@@ -127,9 +127,9 @@ const GraphView = ({
zoomOut,
zoomTo,
setTransform: transform,
project: onLoadProject(currentStore),
getElements: onLoadGetElements(currentStore),
toObject: onLoadToObject(currentStore),
project: onLoadProject(store.getState),
getElements: onLoadGetElements(store.getState),
toObject: onLoadToObject(store.getState),
});
}
+21 -9
View File
@@ -1,7 +1,7 @@
import React, { memo, useMemo, ComponentType, MouseEvent } from 'react';
import { useStoreState, useStoreActions } from '../../store/hooks';
import { Node, NodeTypesType, WrapNodeProps, Edge } from '../../types';
import { useStore } from '../../store';
import { Node, NodeTypesType, ReactFlowState, Edge, WrapNodeProps } from '../../types';
interface NodeRendererProps {
nodeTypes: NodeTypesType;
selectNodesOnDrag: boolean;
@@ -19,14 +19,26 @@ interface NodeRendererProps {
onlyRenderVisibleElements: boolean;
}
const selector = (s: ReactFlowState) => ({
transform: s.transform,
selectedElements: s.selectedElements,
nodesDraggable: s.nodesDraggable,
nodesConnectable: s.nodesConnectable,
elementsSelectable: s.elementsSelectable,
nodes: s.nodes,
updateNodeDimensions: s.updateNodeDimensions,
});
const NodeRenderer = (props: NodeRendererProps) => {
const transform = useStoreState((state) => state.transform);
const selectedElements = useStoreState((state) => state.selectedElements);
const nodesDraggable = useStoreState((state) => state.nodesDraggable);
const nodesConnectable = useStoreState((state) => state.nodesConnectable);
const elementsSelectable = useStoreState((state) => state.elementsSelectable);
const nodes = useStoreState((state) => state.nodes);
const updateNodeDimensions = useStoreActions((actions) => actions.updateNodeDimensions);
const {
transform,
selectedElements,
nodesDraggable,
nodesConnectable,
elementsSelectable,
nodes,
updateNodeDimensions,
} = useStore(selector);
// const visibleNodes = props.onlyRenderVisibleElements
// ? getNodesInside(nodes, { x: 0, y: 0, width, height }, transform, true)
+18 -13
View File
@@ -1,21 +1,26 @@
import React, { FC, useContext, useMemo } from 'react';
import { Provider, ReactReduxContext } from 'react-redux';
import React, { FC } from 'react';
import store from '../../store';
import { Provider, createStore } from '../../store';
// import { ReactFlowState } from '../../types';
// const reactFlowVersionSelector = (s: ReactFlowState) => s.reactFlowVersion;
const Wrapper: FC = ({ children }) => {
const contextValue = useContext(ReactReduxContext);
const isWrappedWithReactFlowProvider = useMemo(() => contextValue?.store?.getState()?.reactFlowVersion, [
contextValue,
]);
// let isWrapped = useRef<boolean>(true);
if (isWrappedWithReactFlowProvider) {
// we need to wrap it with a fragment because it's not allowed for children to be a ReactNode
// https://github.com/DefinitelyTyped/DefinitelyTyped/issues/18051
return <>{children}</>;
}
// try {
// useStoreApi();
// } catch {
// isWrapped.current = false;
// }
return <Provider store={store}>{children}</Provider>;
// if (isWrapped) {
// // we need to wrap it with a fragment because it's not allowed for children to be a ReactNode
// // https://github.com/DefinitelyTyped/DefinitelyTyped/issues/18051
// return <>{children}</>;
// }
return <Provider createStore={createStore}>{children}</Provider>;
};
Wrapper.displayName = 'ReactFlowWrapper';
+13 -11
View File
@@ -5,8 +5,8 @@ import { select, pointer } from 'd3-selection';
import { clamp } from '../../utils';
import useKeyPress from '../../hooks/useKeyPress';
import useResizeHandler from '../../hooks/useResizeHandler';
import { useStoreState, useStoreActions, useStore } from '../../store/hooks';
import { FlowTransform, TranslateExtent, PanOnScrollMode, KeyCode } from '../../types';
import { useStore, useStoreApi } from '../../store';
import { FlowTransform, TranslateExtent, PanOnScrollMode, KeyCode, ReactFlowState } from '../../types';
interface ZoomPaneProps {
selectionKeyPressed: boolean;
@@ -42,6 +42,15 @@ const eventToFlowTransform = (eventTransform: any): FlowTransform => ({
const hasNoWheelClass = (event: any) => event.target.closest('.nowheel');
const selector = (s: ReactFlowState) => ({
d3Zoom: s.d3Zoom,
d3Selection: s.d3Selection,
d3ZoomHandler: s.d3ZoomHandler,
initD3Zoom: s.initD3Zoom,
updateTransform: s.updateTransform,
});
const ZoomPane = ({
onMove,
onMoveStart,
@@ -62,17 +71,10 @@ const ZoomPane = ({
preventScrolling = true,
children,
}: ZoomPaneProps) => {
const store = useStoreApi();
const zoomPane = useRef<HTMLDivElement>(null);
const prevTransform = useRef<FlowTransform>({ x: 0, y: 0, zoom: 0 });
const store = useStore();
const d3Zoom = useStoreState((s) => s.d3Zoom);
const d3Selection = useStoreState((s) => s.d3Selection);
const d3ZoomHandler = useStoreState((s) => s.d3ZoomHandler);
const initD3Zoom = useStoreActions((actions) => actions.initD3Zoom);
const updateTransform = useStoreActions((actions) => actions.updateTransform);
const { d3Zoom, d3Selection, d3ZoomHandler, initD3Zoom, updateTransform } = useStore(selector);
const zoomActivationKeyPressed = useKeyPress(zoomActivationKeyCode);
useResizeHandler(zoomPane);