From 66b5c95ac5da1a8ee29e263e8a150af7a7e8f9da Mon Sep 17 00:00:00 2001 From: moklick Date: Tue, 19 Dec 2023 11:13:48 +0100 Subject: [PATCH] refactor(react): reduce initial store.setState calls --- .../src/components/EdgeWrapper/index.tsx | 5 ++-- .../src/components/NodeWrapper/index.tsx | 1 + .../src/components/StoreUpdater/index.tsx | 17 +++++++++-- .../src/container/EdgeRenderer/index.tsx | 3 -- .../react/src/container/GraphView/index.tsx | 4 +-- .../react/src/container/ReactFlow/index.tsx | 28 +++++++++---------- packages/react/src/store/initialState.ts | 1 + packages/react/src/types/edges.ts | 1 - packages/react/src/types/store.ts | 1 + 9 files changed, 34 insertions(+), 27 deletions(-) diff --git a/packages/react/src/components/EdgeWrapper/index.tsx b/packages/react/src/components/EdgeWrapper/index.tsx index 926860ff..2a30116b 100644 --- a/packages/react/src/components/EdgeWrapper/index.tsx +++ b/packages/react/src/components/EdgeWrapper/index.tsx @@ -34,7 +34,6 @@ function EdgeWrapper({ onEdgeUpdateEnd, rfId, edgeTypes, - elevateEdgesOnSelect, noPanClassName, onError, }: EdgeWrapperProps): JSX.Element | null { @@ -90,7 +89,7 @@ function EdgeWrapper({ zIndex: edge.zIndex, sourceNode, targetNode, - elevateOnSelect: elevateEdgesOnSelect, + elevateOnSelect: store.elevateEdgesOnSelect, }); return { @@ -98,7 +97,7 @@ function EdgeWrapper({ ...(edgePosition || nullPosition), }; }, - [edge.source, edge.target, edge.selected, edge.zIndex, elevateEdgesOnSelect] + [edge.source, edge.target, edge.selected, edge.zIndex] ), shallow ); diff --git a/packages/react/src/components/NodeWrapper/index.tsx b/packages/react/src/components/NodeWrapper/index.tsx index 5db82d5b..cc593439 100644 --- a/packages/react/src/components/NodeWrapper/index.tsx +++ b/packages/react/src/components/NodeWrapper/index.tsx @@ -18,6 +18,7 @@ import { handleNodeClick } from '../Nodes/utils'; import type { NodeWrapperProps } from '../../types'; import { arrowKeyDiffs, builtinNodeTypes } from './utils'; import { shallow } from 'zustand/shallow'; + const NodeWrapper = ({ id, onClick, diff --git a/packages/react/src/components/StoreUpdater/index.tsx b/packages/react/src/components/StoreUpdater/index.tsx index f49dec43..948c50fc 100644 --- a/packages/react/src/components/StoreUpdater/index.tsx +++ b/packages/react/src/components/StoreUpdater/index.tsx @@ -5,10 +5,11 @@ */ import { useEffect, useRef } from 'react'; import { shallow } from 'zustand/shallow'; -import { type CoordinateExtent } from '@xyflow/system'; +import { infiniteExtent, type CoordinateExtent } from '@xyflow/system'; import { useStore, useStoreApi } from '../../hooks/useStore'; import type { Node, Edge, ReactFlowState, ReactFlowProps, FitViewOptions } from '../../types'; +import { initNodeOrigin } from '../../container/ReactFlow'; // these fields exist in the global store and we need to keep them up to date const reactFlowFieldsToTrack = [ @@ -27,6 +28,7 @@ const reactFlowFieldsToTrack = [ 'edgesFocusable', 'edgesUpdatable', 'elevateNodesOnSelect', + 'elevateEdgesOnSelect', 'minZoom', 'maxZoom', 'nodeExtent', @@ -103,7 +105,18 @@ const StoreUpdater = (props: StoreUpdaterProps) => { }; }, []); - const previousFields = useRef>({}); + const previousFields = useRef>({ + // these are values that are also passed directly to other components + // than the StoreUpdater. We can reduce the number of setStore calls + // by setting the same values here as prev fields. + translateExtent: infiniteExtent, + nodeOrigin: initNodeOrigin, + minZoom: 0.5, + maxZoom: 2, + elementsSelectable: true, + noPanClassName: 'nopan', + rfId: '1', + }); useEffect( () => { diff --git a/packages/react/src/container/EdgeRenderer/index.tsx b/packages/react/src/container/EdgeRenderer/index.tsx index 83489d24..9c289c87 100644 --- a/packages/react/src/container/EdgeRenderer/index.tsx +++ b/packages/react/src/container/EdgeRenderer/index.tsx @@ -23,7 +23,6 @@ type EdgeRendererProps = Pick< | 'onEdgeUpdateEnd' | 'edgeUpdaterRadius' | 'noPanClassName' - | 'elevateEdgesOnSelect' | 'rfId' | 'disableKeyboardA11y' | 'edgeTypes' @@ -44,7 +43,6 @@ const selector = (s: ReactFlowState) => ({ const EdgeRenderer = ({ defaultMarkerColor, onlyRenderVisibleElements, - elevateEdgesOnSelect, rfId, edgeTypes, noPanClassName, @@ -89,7 +87,6 @@ const EdgeRenderer = ({ rfId={rfId} onError={onError} edgeTypes={edgeTypes} - elevateEdgesOnSelect={elevateEdgesOnSelect} /> ); })} diff --git a/packages/react/src/container/GraphView/index.tsx b/packages/react/src/container/GraphView/index.tsx index 116b4d26..217e90c2 100644 --- a/packages/react/src/container/GraphView/index.tsx +++ b/packages/react/src/container/GraphView/index.tsx @@ -12,7 +12,7 @@ import useNodeOrEdgeTypesWarning from './useNodeOrEdgeTypesWarning'; export type GraphViewProps = Omit< ReactFlowProps, - 'onSelectionChange' | 'nodes' | 'edges' | 'onMove' | 'onMoveStart' | 'onMoveEnd' + 'onSelectionChange' | 'nodes' | 'edges' | 'onMove' | 'onMoveStart' | 'onMoveEnd' | 'elevateEdgesOnSelect' > & Required< Pick< @@ -96,7 +96,6 @@ const GraphView = ({ noDragClassName, noWheelClassName, noPanClassName, - elevateEdgesOnSelect, disableKeyboardA11y, nodeOrigin, nodeExtent, @@ -164,7 +163,6 @@ const GraphView = ({ edgeUpdaterRadius={edgeUpdaterRadius} defaultMarkerColor={defaultMarkerColor} noPanClassName={noPanClassName} - elevateEdgesOnSelect={!!elevateEdgesOnSelect} disableKeyboardA11y={disableKeyboardA11y} rfId={rfId} > diff --git a/packages/react/src/container/ReactFlow/index.tsx b/packages/react/src/container/ReactFlow/index.tsx index 3adacfeb..48ff13c6 100644 --- a/packages/react/src/container/ReactFlow/index.tsx +++ b/packages/react/src/container/ReactFlow/index.tsx @@ -2,7 +2,6 @@ import { forwardRef, type CSSProperties } from 'react'; import cc from 'classcat'; import { ConnectionLineType, - ConnectionMode, PanOnScrollMode, SelectionMode, infiniteExtent, @@ -21,8 +20,7 @@ import Wrapper from './Wrapper'; import type { ReactFlowProps, ReactFlowRefType } from '../../types'; import useColorModeClass from '../../hooks/useColorModeClass'; -const initNodeOrigin: NodeOrigin = [0, 0]; -const initSnapGrid: [number, number] = [15, 15]; +export const initNodeOrigin: NodeOrigin = [0, 0]; const initDefaultViewport: Viewport = { x: 0, y: 0, zoom: 1 }; const wrapperStyle: CSSProperties = { @@ -72,7 +70,7 @@ const ReactFlow = forwardRef( onSelectionContextMenu, onSelectionStart, onSelectionEnd, - connectionMode = ConnectionMode.Strict, + connectionMode, connectionLineType = ConnectionLineType.Bezier, connectionLineStyle, connectionLineComponent, @@ -84,10 +82,10 @@ const ReactFlow = forwardRef( panActivationKeyCode = 'Space', multiSelectionKeyCode = isMacOs() ? 'Meta' : 'Control', zoomActivationKeyCode = isMacOs() ? 'Meta' : 'Control', - snapToGrid = false, - snapGrid = initSnapGrid, + snapToGrid, + snapGrid, onlyRenderVisibleElements = false, - selectNodesOnDrag = true, + selectNodesOnDrag, nodesDraggable, nodesConnectable, nodesFocusable, @@ -130,18 +128,18 @@ const ReactFlow = forwardRef( noDragClassName = 'nodrag', noWheelClassName = 'nowheel', noPanClassName = 'nopan', - fitView = false, + fitView, fitViewOptions, - connectOnClick = true, + connectOnClick, attributionPosition, proOptions, defaultEdgeOptions, - elevateNodesOnSelect = true, - elevateEdgesOnSelect = false, + elevateNodesOnSelect, + elevateEdgesOnSelect, disableKeyboardA11y = false, - autoPanOnConnect = true, - autoPanOnNodeDrag = true, - connectionRadius = 20, + autoPanOnConnect, + autoPanOnNodeDrag, + connectionRadius, isValidConnection, onError, style, @@ -226,7 +224,6 @@ const ReactFlow = forwardRef( noDragClassName={noDragClassName} noWheelClassName={noWheelClassName} noPanClassName={noPanClassName} - elevateEdgesOnSelect={elevateEdgesOnSelect} rfId={rfId} disableKeyboardA11y={disableKeyboardA11y} nodeOrigin={nodeOrigin} @@ -251,6 +248,7 @@ const ReactFlow = forwardRef( edgesUpdatable={edgesUpdatable} elementsSelectable={elementsSelectable} elevateNodesOnSelect={elevateNodesOnSelect} + elevateEdgesOnSelect={elevateEdgesOnSelect} minZoom={minZoom} maxZoom={maxZoom} nodeExtent={nodeExtent} diff --git a/packages/react/src/store/initialState.ts b/packages/react/src/store/initialState.ts index 87a4fc9e..c8f92903 100644 --- a/packages/react/src/store/initialState.ts +++ b/packages/react/src/store/initialState.ts @@ -83,6 +83,7 @@ const getInitialState = ({ edgesUpdatable: true, elementsSelectable: true, elevateNodesOnSelect: true, + elevateEdgesOnSelect: false, fitViewOnInit: false, fitViewDone: false, fitViewOnInitOptions: undefined, diff --git a/packages/react/src/types/edges.ts b/packages/react/src/types/edges.ts index a1a06725..f805da8c 100644 --- a/packages/react/src/types/edges.ts +++ b/packages/react/src/types/edges.ts @@ -78,7 +78,6 @@ export type EdgeWrapperProps = { rfId?: string; edgeTypes?: EdgeTypes; onError?: OnError; - elevateEdgesOnSelect?: boolean; }; export type DefaultEdgeOptions = DefaultEdgeOptionsBase; diff --git a/packages/react/src/types/store.ts b/packages/react/src/types/store.ts index bf5a5c11..a4cad399 100644 --- a/packages/react/src/types/store.ts +++ b/packages/react/src/types/store.ts @@ -88,6 +88,7 @@ export type ReactFlowStore = { edgesUpdatable: boolean; elementsSelectable: boolean; elevateNodesOnSelect: boolean; + elevateEdgesOnSelect: boolean; selectNodesOnDrag: boolean; multiSelectionActive: boolean;