From 23aa8bb2707406c79a28b0cba5d49752e8335e81 Mon Sep 17 00:00:00 2001 From: GeoffreyLiu Date: Mon, 14 Nov 2022 08:30:09 +0800 Subject: [PATCH] refactor: use existing d3Selection to get the element ref --- .../components/reactflow/basic-props.cy.tsx | 29 ------------------- .../vite-app/cypress/support/RefReactFlow.tsx | 12 -------- .../components/EdgeLabelRenderer/index.tsx | 22 ++++++-------- .../src/components/StoreUpdater/index.tsx | 14 ++------- packages/core/src/constants/component.ts | 1 - .../core/src/container/GraphView/index.tsx | 3 +- .../core/src/container/ReactFlow/index.tsx | 20 ++----------- packages/core/src/store/initialState.ts | 1 - packages/core/src/types/general.ts | 5 +--- 9 files changed, 15 insertions(+), 92 deletions(-) delete mode 100644 examples/vite-app/cypress/support/RefReactFlow.tsx delete mode 100644 packages/core/src/constants/component.ts diff --git a/examples/vite-app/cypress/components/reactflow/basic-props.cy.tsx b/examples/vite-app/cypress/components/reactflow/basic-props.cy.tsx index 8738436e..d777531e 100644 --- a/examples/vite-app/cypress/components/reactflow/basic-props.cy.tsx +++ b/examples/vite-app/cypress/components/reactflow/basic-props.cy.tsx @@ -2,7 +2,6 @@ import ReactFlow, { EdgeProps } from 'reactflow'; import ControlledFlow from '../../support/ControlledFlow'; import * as simpleflow from '../../fixtures/simpleflow'; -import { RefReactFlow } from '../../support/RefReactFlow'; describe(': Basic Props', () => { describe('uses defaultNodes and defaultEdges', () => { @@ -195,32 +194,4 @@ describe(': Basic Props', () => { cy.mount(); cy.get('.react-flow').should('have.class', 'custom'); }); - - it('uses function ref', () => { - let pResolve: ((element: HTMLDivElement | PromiseLike | null) => void) | null = null; - const promise: Promise = new Promise((resolve) => { - pResolve = resolve; - }); - - function ref(root: HTMLDivElement | null) { - pResolve && pResolve(root); - } - - cy.mount(); - cy.wrap(promise).should('be.instanceOf', HTMLDivElement); - }); - - it('use mutable ref', () => { - let pResolve: ((element: HTMLDivElement | PromiseLike | null) => void) | null = null; - const promise: Promise = new Promise((resolve) => { - pResolve = resolve; - }); - - function onGetRef(root: HTMLDivElement | null) { - pResolve && pResolve(root); - } - - cy.mount(); - cy.wrap(promise).should('be.instanceOf', HTMLDivElement); - }); }); diff --git a/examples/vite-app/cypress/support/RefReactFlow.tsx b/examples/vite-app/cypress/support/RefReactFlow.tsx deleted file mode 100644 index baec9696..00000000 --- a/examples/vite-app/cypress/support/RefReactFlow.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import { useEffect, useRef } from 'react'; -import ReactFlow from 'reactflow'; - -export function RefReactFlow({ onGetRef }: { onGetRef: (element: HTMLDivElement | null) => void }) { - const ref = useRef(null); - - useEffect(() => { - onGetRef(ref.current); - }, []); - - return ; -} diff --git a/packages/core/src/components/EdgeLabelRenderer/index.tsx b/packages/core/src/components/EdgeLabelRenderer/index.tsx index 815916f0..c98665ef 100644 --- a/packages/core/src/components/EdgeLabelRenderer/index.tsx +++ b/packages/core/src/components/EdgeLabelRenderer/index.tsx @@ -1,22 +1,18 @@ import type { ReactNode } from 'react'; import { createPortal } from 'react-dom'; -import { useStoreApi } from '../../hooks/useStore'; -import { EDGE_LABEL_RENDERER_MAIN_CLASS } from '../../constants/component'; +import { useStore } from '../../hooks/useStore'; +import { ReactFlowState } from '../../types'; + +const selector = (s: ReactFlowState) => ({ + d3Selection: s.d3Selection, +}); function EdgeLabelRenderer({ children }: { children: ReactNode }) { - const store = useStoreApi(); - const { - rootElementRef: { current: rootElement }, - } = store.getState(); + const { d3Selection } = useStore(selector); - if (!rootElement) { - return null; - } + const edgeLabelRendererElement = d3Selection?.select('.react-flow__edgelabel-renderer').node(); - const collection = rootElement.getElementsByClassName(EDGE_LABEL_RENDERER_MAIN_CLASS); - - const edgeLabelRendererElement = collection.item(0); - if (!edgeLabelRendererElement) { + if (!edgeLabelRendererElement || !(edgeLabelRendererElement instanceof HTMLDivElement)) { return null; } diff --git a/packages/core/src/components/StoreUpdater/index.tsx b/packages/core/src/components/StoreUpdater/index.tsx index bb3f89ca..2f98a453 100644 --- a/packages/core/src/components/StoreUpdater/index.tsx +++ b/packages/core/src/components/StoreUpdater/index.tsx @@ -3,15 +3,7 @@ import { StoreApi } from 'zustand'; import shallow from 'zustand/shallow'; import { useStore, useStoreApi } from '../../hooks/useStore'; -import type { - Node, - Edge, - ReactFlowState, - CoordinateExtent, - ReactFlowProps, - ReactFlowStore, - RootElementRef, -} from '../../types'; +import type { Node, Edge, ReactFlowState, CoordinateExtent, ReactFlowProps, ReactFlowStore } from '../../types'; type StoreUpdaterProps = Pick< ReactFlowProps, @@ -52,7 +44,7 @@ type StoreUpdaterProps = Pick< | 'onSelectionDragStop' | 'noPanClassName' | 'nodeOrigin' -> & { rfId: string; rootElementRef: RootElementRef }; +> & { rfId: string }; const selector = (s: ReactFlowState) => ({ setNodes: s.setNodes, @@ -125,7 +117,6 @@ const StoreUpdater = ({ noPanClassName, nodeOrigin, rfId, - rootElementRef, }: StoreUpdaterProps) => { const { setNodes, @@ -178,7 +169,6 @@ const StoreUpdater = ({ useDirectStoreUpdater('noPanClassName', noPanClassName, store.setState); useDirectStoreUpdater('nodeOrigin', nodeOrigin, store.setState); useDirectStoreUpdater('rfId', rfId, store.setState); - useDirectStoreUpdater('rootElementRef', rootElementRef, store.setState); useStoreUpdater(nodes, setNodes); useStoreUpdater(edges, setEdges); diff --git a/packages/core/src/constants/component.ts b/packages/core/src/constants/component.ts deleted file mode 100644 index abb2f46b..00000000 --- a/packages/core/src/constants/component.ts +++ /dev/null @@ -1 +0,0 @@ -export const EDGE_LABEL_RENDERER_MAIN_CLASS = 'react-flow__edgelabel-renderer' diff --git a/packages/core/src/container/GraphView/index.tsx b/packages/core/src/container/GraphView/index.tsx index 98f9bede..3af02659 100644 --- a/packages/core/src/container/GraphView/index.tsx +++ b/packages/core/src/container/GraphView/index.tsx @@ -6,7 +6,6 @@ import EdgeRenderer from '../EdgeRenderer'; import ViewportWrapper from '../Viewport'; import useOnInitHandler from '../../hooks/useOnInitHandler'; import type { EdgeTypesWrapped, NodeTypesWrapped, ReactFlowProps } from '../../types'; -import { EDGE_LABEL_RENDERER_MAIN_CLASS } from '../../constants/component'; export type GraphViewProps = Omit & Required< @@ -159,7 +158,7 @@ const GraphView = ({ disableKeyboardA11y={disableKeyboardA11y} rfId={rfId} /> -
+
( const edgeTypesWrapped = useNodeOrEdgeTypes(edgeTypes, createEdgeTypes) as EdgeTypesWrapped; const rfId = id || '1'; - const rootElementRef = useRef(null); - - function setRootRef(element: HTMLDivElement | null) { - rootElementRef.current = element; - - if (typeof ref === 'function') { - ref(element); - return; - } - - if (ref) { - ref.current = element; - } - } - return (
( noPanClassName={noPanClassName} nodeOrigin={nodeOrigin} rfId={rfId} - rootElementRef={rootElementRef} /> {children} diff --git a/packages/core/src/store/initialState.ts b/packages/core/src/store/initialState.ts index a0353868..ab918e65 100644 --- a/packages/core/src/store/initialState.ts +++ b/packages/core/src/store/initialState.ts @@ -54,7 +54,6 @@ const initialState: ReactFlowStore = { connectOnClick: true, ariaLiveMessage: '', - rootElementRef: { current: null } }; export default initialState; diff --git a/packages/core/src/types/general.ts b/packages/core/src/types/general.ts index 48222f49..b18f4d32 100644 --- a/packages/core/src/types/general.ts +++ b/packages/core/src/types/general.ts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ -import type { MouseEvent as ReactMouseEvent, ComponentType, MemoExoticComponent, MutableRefObject } from 'react'; +import type { MouseEvent as ReactMouseEvent, ComponentType, MemoExoticComponent } from 'react'; import type { Selection as D3Selection, ZoomBehavior } from 'd3'; import type { XYPosition, Rect, Transform, CoordinateExtent } from './utils'; @@ -129,8 +129,6 @@ export type ViewportHelperFunctions = { viewportInitialized: boolean; }; -export type RootElementRef = MutableRefObject - export type ReactFlowStore = { rfId: string; width: number; @@ -210,7 +208,6 @@ export type ReactFlowStore = { onSelectionChange?: OnSelectionChangeFunc; ariaLiveMessage: string; - rootElementRef: RootElementRef }; export type ReactFlowActions = {