refactor(state): replace redux with zustand
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user