refactor(nodeTypes/edgeTypes): show warning when not memoized closes #1620
This commit is contained in:
@@ -27,6 +27,7 @@ const initBgColor = '#1A192B';
|
|||||||
|
|
||||||
const connectionLineStyle = { stroke: '#fff' };
|
const connectionLineStyle = { stroke: '#fff' };
|
||||||
const snapGrid: SnapGrid = [16, 16];
|
const snapGrid: SnapGrid = [16, 16];
|
||||||
|
|
||||||
const nodeTypes = {
|
const nodeTypes = {
|
||||||
selectorNode: ColorSelectorNode,
|
selectorNode: ColorSelectorNode,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import ReactFlow, {
|
|||||||
Controls,
|
Controls,
|
||||||
Background,
|
Background,
|
||||||
ReactFlowInstance,
|
ReactFlowInstance,
|
||||||
EdgeTypesType,
|
EdgeTypes,
|
||||||
Connection,
|
Connection,
|
||||||
Edge,
|
Edge,
|
||||||
MarkerType,
|
MarkerType,
|
||||||
@@ -102,7 +102,7 @@ const initialEdges: Edge[] = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const edgeTypes: EdgeTypesType = {
|
const edgeTypes: EdgeTypes = {
|
||||||
custom: CustomEdge,
|
custom: CustomEdge,
|
||||||
custom2: CustomEdge2,
|
custom2: CustomEdge2,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import ReactFlow, {
|
|||||||
addEdge,
|
addEdge,
|
||||||
Background,
|
Background,
|
||||||
ReactFlowInstance,
|
ReactFlowInstance,
|
||||||
EdgeTypesType,
|
EdgeTypes,
|
||||||
Connection,
|
Connection,
|
||||||
useNodesState,
|
useNodesState,
|
||||||
useEdgesState,
|
useEdgesState,
|
||||||
@@ -20,7 +20,7 @@ const onInit = (reactFlowInstance: ReactFlowInstance) => reactFlowInstance.fitVi
|
|||||||
|
|
||||||
const { nodes: initialNodes, edges: initialEdges } = createElements();
|
const { nodes: initialNodes, edges: initialEdges } = createElements();
|
||||||
|
|
||||||
const edgeTypes: EdgeTypesType = {
|
const edgeTypes: EdgeTypes = {
|
||||||
floating: FloatingEdge,
|
floating: FloatingEdge,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import ReactFlow, {
|
|||||||
Connection,
|
Connection,
|
||||||
Edge,
|
Edge,
|
||||||
NodeProps,
|
NodeProps,
|
||||||
NodeTypesType,
|
NodeTypes,
|
||||||
useNodesState,
|
useNodesState,
|
||||||
useEdgesState,
|
useEdgesState,
|
||||||
} from 'react-flow-renderer';
|
} from 'react-flow-renderer';
|
||||||
@@ -43,7 +43,7 @@ const NodeB: FC<NodeProps> = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
type NodeTypesObject = {
|
type NodeTypesObject = {
|
||||||
[key: string]: NodeTypesType;
|
[key: string]: NodeTypes;
|
||||||
};
|
};
|
||||||
|
|
||||||
const nodeTypesObjects: NodeTypesObject = {
|
const nodeTypesObjects: NodeTypesObject = {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { useCallback } from 'react';
|
|||||||
|
|
||||||
import ReactFlow, {
|
import ReactFlow, {
|
||||||
useReactFlow,
|
useReactFlow,
|
||||||
NodeTypesType,
|
NodeTypes,
|
||||||
addEdge,
|
addEdge,
|
||||||
ReactFlowProvider,
|
ReactFlowProvider,
|
||||||
Node,
|
Node,
|
||||||
@@ -172,7 +172,7 @@ const initialEdges: Edge[] = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const nodeTypes: NodeTypesType = {
|
const nodeTypes: NodeTypes = {
|
||||||
custom: CustomNode,
|
custom: CustomNode,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { useCallback, CSSProperties } from 'react';
|
import { useCallback, CSSProperties } from 'react';
|
||||||
|
|
||||||
import ReactFlow, {
|
import ReactFlow, {
|
||||||
NodeTypesType,
|
NodeTypes,
|
||||||
addEdge,
|
addEdge,
|
||||||
useReactFlow,
|
useReactFlow,
|
||||||
ReactFlowProvider,
|
ReactFlowProvider,
|
||||||
@@ -28,7 +28,7 @@ const initialNodes: Node[] = [
|
|||||||
|
|
||||||
const buttonWrapperStyles: CSSProperties = { position: 'absolute', right: 10, top: 10, zIndex: 10 };
|
const buttonWrapperStyles: CSSProperties = { position: 'absolute', right: 10, top: 10, zIndex: 10 };
|
||||||
|
|
||||||
const nodeTypes: NodeTypesType = {
|
const nodeTypes: NodeTypes = {
|
||||||
custom: CustomNode,
|
custom: CustomNode,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import ReactFlow, {
|
|||||||
Edge,
|
Edge,
|
||||||
OnConnectStartParams,
|
OnConnectStartParams,
|
||||||
NodeProps,
|
NodeProps,
|
||||||
NodeTypesType,
|
NodeTypes,
|
||||||
useNodesState,
|
useNodesState,
|
||||||
useEdgesState,
|
useEdgesState,
|
||||||
} from 'react-flow-renderer';
|
} from 'react-flow-renderer';
|
||||||
@@ -43,7 +43,7 @@ const CustomNode: FC<NodeProps> = ({ id }) => (
|
|||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
||||||
const nodeTypes: NodeTypesType = {
|
const nodeTypes: NodeTypes = {
|
||||||
custominput: CustomInput,
|
custominput: CustomInput,
|
||||||
customnode: CustomNode,
|
customnode: CustomNode,
|
||||||
};
|
};
|
||||||
|
|||||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "react-flow-renderer",
|
"name": "react-flow-renderer",
|
||||||
"version": "10.0.0-next.41",
|
"version": "10.0.0-next.42",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "react-flow-renderer",
|
"name": "react-flow-renderer",
|
||||||
"version": "10.0.0-next.41",
|
"version": "10.0.0-next.42",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.16.7",
|
"@babel/runtime": "^7.16.7",
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "react-flow-renderer",
|
"name": "react-flow-renderer",
|
||||||
"version": "10.0.0-next.41",
|
"version": "10.0.0-next.42",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import wrapEdge from '../../components/Edges/wrapEdge';
|
|||||||
import { rectToBox } from '../../utils';
|
import { rectToBox } from '../../utils';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
EdgeTypesType,
|
EdgeTypes,
|
||||||
EdgeProps,
|
EdgeProps,
|
||||||
HandleElement,
|
HandleElement,
|
||||||
Position,
|
Position,
|
||||||
@@ -16,16 +16,18 @@ import {
|
|||||||
NodeHandleBounds,
|
NodeHandleBounds,
|
||||||
} from '../../types';
|
} from '../../types';
|
||||||
|
|
||||||
export function createEdgeTypes(edgeTypes: EdgeTypesType): EdgeTypesType {
|
export type CreateEdgeTypes = (edgeTypes: EdgeTypes) => EdgeTypes;
|
||||||
const standardTypes: EdgeTypesType = {
|
|
||||||
|
export function createEdgeTypes(edgeTypes: EdgeTypes): EdgeTypes {
|
||||||
|
const standardTypes: EdgeTypes = {
|
||||||
default: wrapEdge((edgeTypes.default || BezierEdge) as ComponentType<EdgeProps>),
|
default: wrapEdge((edgeTypes.default || BezierEdge) as ComponentType<EdgeProps>),
|
||||||
straight: wrapEdge((edgeTypes.bezier || StraightEdge) as ComponentType<EdgeProps>),
|
straight: wrapEdge((edgeTypes.bezier || StraightEdge) as ComponentType<EdgeProps>),
|
||||||
step: wrapEdge((edgeTypes.step || StepEdge) as ComponentType<EdgeProps>),
|
step: wrapEdge((edgeTypes.step || StepEdge) as ComponentType<EdgeProps>),
|
||||||
smoothstep: wrapEdge((edgeTypes.step || SmoothStepEdge) as ComponentType<EdgeProps>),
|
smoothstep: wrapEdge((edgeTypes.step || SmoothStepEdge) as ComponentType<EdgeProps>),
|
||||||
};
|
};
|
||||||
|
|
||||||
const wrappedTypes = {} as EdgeTypesType;
|
const wrappedTypes = {} as EdgeTypes;
|
||||||
const specialTypes: EdgeTypesType = Object.keys(edgeTypes)
|
const specialTypes: EdgeTypes = Object.keys(edgeTypes)
|
||||||
.filter((k) => !['default', 'bezier'].includes(k))
|
.filter((k) => !['default', 'bezier'].includes(k))
|
||||||
.reduce((res, key) => {
|
.reduce((res, key) => {
|
||||||
res[key] = wrapEdge((edgeTypes[key] || BezierEdge) as ComponentType<EdgeProps>);
|
res[key] = wrapEdge((edgeTypes[key] || BezierEdge) as ComponentType<EdgeProps>);
|
||||||
|
|||||||
@@ -5,11 +5,11 @@ import NodeRenderer from '../NodeRenderer';
|
|||||||
import EdgeRenderer from '../EdgeRenderer';
|
import EdgeRenderer from '../EdgeRenderer';
|
||||||
import Viewport from '../Viewport';
|
import Viewport from '../Viewport';
|
||||||
import useOnInitHandler from '../../hooks/useOnInitHandler';
|
import useOnInitHandler from '../../hooks/useOnInitHandler';
|
||||||
import { NodeTypesType, EdgeTypesType, ConnectionLineType, KeyCode, ReactFlowProps } from '../../types';
|
import { NodeTypes, EdgeTypes, ConnectionLineType, KeyCode, ReactFlowProps } from '../../types';
|
||||||
|
|
||||||
export interface GraphViewProps extends Omit<ReactFlowProps, 'onSelectionChange' | 'nodes' | 'edges'> {
|
export interface GraphViewProps extends Omit<ReactFlowProps, 'onSelectionChange' | 'nodes' | 'edges'> {
|
||||||
nodeTypes: NodeTypesType;
|
nodeTypes: NodeTypes;
|
||||||
edgeTypes: EdgeTypesType;
|
edgeTypes: EdgeTypes;
|
||||||
selectionKeyCode: KeyCode;
|
selectionKeyCode: KeyCode;
|
||||||
deleteKeyCode: KeyCode;
|
deleteKeyCode: KeyCode;
|
||||||
multiSelectionKeyCode: KeyCode;
|
multiSelectionKeyCode: KeyCode;
|
||||||
|
|||||||
@@ -3,10 +3,10 @@ import shallow from 'zustand/shallow';
|
|||||||
|
|
||||||
import useVisibleNodes from '../../hooks/useVisibleNodes';
|
import useVisibleNodes from '../../hooks/useVisibleNodes';
|
||||||
import { useStore } from '../../store';
|
import { useStore } from '../../store';
|
||||||
import { Node, NodeTypesType, Position, ReactFlowState, WrapNodeProps } from '../../types';
|
import { Node, NodeTypes, Position, ReactFlowState, WrapNodeProps } from '../../types';
|
||||||
|
|
||||||
interface NodeRendererProps {
|
interface NodeRendererProps {
|
||||||
nodeTypes: NodeTypesType;
|
nodeTypes: NodeTypes;
|
||||||
selectNodesOnDrag: boolean;
|
selectNodesOnDrag: boolean;
|
||||||
onNodeClick?: (event: MouseEvent, element: Node) => void;
|
onNodeClick?: (event: MouseEvent, element: Node) => void;
|
||||||
onNodeDoubleClick?: (event: MouseEvent, element: Node) => void;
|
onNodeDoubleClick?: (event: MouseEvent, element: Node) => void;
|
||||||
|
|||||||
@@ -5,18 +5,20 @@ import InputNode from '../../components/Nodes/InputNode';
|
|||||||
import OutputNode from '../../components/Nodes/OutputNode';
|
import OutputNode from '../../components/Nodes/OutputNode';
|
||||||
import GroupNode from '../../components/Nodes/GroupNode';
|
import GroupNode from '../../components/Nodes/GroupNode';
|
||||||
import wrapNode from '../../components/Nodes/wrapNode';
|
import wrapNode from '../../components/Nodes/wrapNode';
|
||||||
import { NodeTypesType, NodeProps } from '../../types';
|
import { NodeTypes, NodeProps } from '../../types';
|
||||||
|
|
||||||
export function createNodeTypes(nodeTypes: NodeTypesType): NodeTypesType {
|
export type CreateNodeTypes = (nodeTypes: NodeTypes) => NodeTypes;
|
||||||
const standardTypes: NodeTypesType = {
|
|
||||||
|
export function createNodeTypes(nodeTypes: NodeTypes): NodeTypes {
|
||||||
|
const standardTypes: NodeTypes = {
|
||||||
input: wrapNode((nodeTypes.input || InputNode) as ComponentType<NodeProps>),
|
input: wrapNode((nodeTypes.input || InputNode) as ComponentType<NodeProps>),
|
||||||
default: wrapNode((nodeTypes.default || DefaultNode) as ComponentType<NodeProps>),
|
default: wrapNode((nodeTypes.default || DefaultNode) as ComponentType<NodeProps>),
|
||||||
output: wrapNode((nodeTypes.output || OutputNode) as ComponentType<NodeProps>),
|
output: wrapNode((nodeTypes.output || OutputNode) as ComponentType<NodeProps>),
|
||||||
group: wrapNode((nodeTypes.group || GroupNode) as ComponentType<NodeProps>),
|
group: wrapNode((nodeTypes.group || GroupNode) as ComponentType<NodeProps>),
|
||||||
};
|
};
|
||||||
|
|
||||||
const wrappedTypes = {} as NodeTypesType;
|
const wrappedTypes = {} as NodeTypes;
|
||||||
const specialTypes: NodeTypesType = Object.keys(nodeTypes)
|
const specialTypes: NodeTypes = Object.keys(nodeTypes)
|
||||||
.filter((k) => !['input', 'default', 'output', 'group'].includes(k))
|
.filter((k) => !['input', 'default', 'output', 'group'].includes(k))
|
||||||
.reduce((res, key) => {
|
.reduce((res, key) => {
|
||||||
res[key] = wrapNode((nodeTypes[key] || DefaultNode) as ComponentType<NodeProps>);
|
res[key] = wrapNode((nodeTypes[key] || DefaultNode) as ComponentType<NodeProps>);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { useMemo, forwardRef } from 'react';
|
import React, { forwardRef } from 'react';
|
||||||
import cc from 'classcat';
|
import cc from 'classcat';
|
||||||
|
|
||||||
import GraphView from '../GraphView';
|
import GraphView from '../GraphView';
|
||||||
@@ -13,10 +13,19 @@ import Attribution from '../../components/Attribution';
|
|||||||
import { createEdgeTypes } from '../EdgeRenderer/utils';
|
import { createEdgeTypes } from '../EdgeRenderer/utils';
|
||||||
import Wrapper from './Wrapper';
|
import Wrapper from './Wrapper';
|
||||||
|
|
||||||
import { ConnectionMode, ConnectionLineType, PanOnScrollMode, ReactFlowProps, ReactFlowRefType } from '../../types';
|
import {
|
||||||
|
ConnectionMode,
|
||||||
|
ConnectionLineType,
|
||||||
|
PanOnScrollMode,
|
||||||
|
ReactFlowProps,
|
||||||
|
ReactFlowRefType,
|
||||||
|
NodeTypes,
|
||||||
|
EdgeTypes,
|
||||||
|
} from '../../types';
|
||||||
|
|
||||||
import '../../style.css';
|
import '../../style.css';
|
||||||
import '../../theme-default.css';
|
import '../../theme-default.css';
|
||||||
|
import { useNodeOrEdgeTypes } from './utils';
|
||||||
|
|
||||||
const defaultNodeTypes = {
|
const defaultNodeTypes = {
|
||||||
input: InputNode,
|
input: InputNode,
|
||||||
@@ -127,8 +136,8 @@ const ReactFlow = forwardRef<ReactFlowRefType, ReactFlowProps>(
|
|||||||
},
|
},
|
||||||
ref
|
ref
|
||||||
) => {
|
) => {
|
||||||
const nodeTypesParsed = useMemo(() => createNodeTypes(nodeTypes), [nodeTypes]);
|
const nodeTypesParsed = useNodeOrEdgeTypes(nodeTypes, createNodeTypes) as NodeTypes;
|
||||||
const edgeTypesParsed = useMemo(() => createEdgeTypes(edgeTypes), [edgeTypes]);
|
const edgeTypesParsed = useNodeOrEdgeTypes(edgeTypes, createEdgeTypes) as EdgeTypes;
|
||||||
const reactFlowClasses = cc(['react-flow', className]);
|
const reactFlowClasses = cc(['react-flow', className]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import { useMemo, useRef } from 'react';
|
||||||
|
import shallow from 'zustand/shallow';
|
||||||
|
|
||||||
|
import { EdgeTypes, NodeTypes } from '../../types';
|
||||||
|
import { CreateEdgeTypes } from '../EdgeRenderer/utils';
|
||||||
|
import { CreateNodeTypes } from '../NodeRenderer/utils';
|
||||||
|
|
||||||
|
export function useNodeOrEdgeTypes(nodeOrEdgeTypes: NodeTypes, createTypes: CreateNodeTypes): NodeTypes;
|
||||||
|
export function useNodeOrEdgeTypes(nodeOrEdgeTypes: EdgeTypes, createTypes: CreateEdgeTypes): EdgeTypes;
|
||||||
|
export function useNodeOrEdgeTypes(nodeOrEdgeTypes: any, createTypes: any): any {
|
||||||
|
const typesKeysRef = useRef<string[] | null>(null);
|
||||||
|
|
||||||
|
const typesParsed = useMemo(() => {
|
||||||
|
if (process.env.NODE_ENV === 'development') {
|
||||||
|
const typeKeys = Object.keys(nodeOrEdgeTypes);
|
||||||
|
if (shallow(typesKeysRef.current, typeKeys)) {
|
||||||
|
console.warn(
|
||||||
|
"React Flow: It looks like that you created a new nodeTypes or edgeTypes object. If this wasn't on purpose please define the nodeTypes/edgeTypes outside of the component or memoize them."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
typesKeysRef.current = typeKeys;
|
||||||
|
}
|
||||||
|
return createTypes(nodeOrEdgeTypes);
|
||||||
|
}, [nodeOrEdgeTypes]);
|
||||||
|
|
||||||
|
return typesParsed;
|
||||||
|
}
|
||||||
@@ -2,8 +2,8 @@ import React, { CSSProperties, HTMLAttributes, MouseEvent as ReactMouseEvent, Wh
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
OnSelectionChangeFunc,
|
OnSelectionChangeFunc,
|
||||||
NodeTypesType,
|
NodeTypes,
|
||||||
EdgeTypesType,
|
EdgeTypes,
|
||||||
Node,
|
Node,
|
||||||
Edge,
|
Edge,
|
||||||
ConnectionMode,
|
ConnectionMode,
|
||||||
@@ -68,8 +68,8 @@ export interface ReactFlowProps extends HTMLAttributes<HTMLDivElement> {
|
|||||||
onPaneScroll?: (event?: WheelEvent) => void;
|
onPaneScroll?: (event?: WheelEvent) => void;
|
||||||
onPaneClick?: (event: ReactMouseEvent) => void;
|
onPaneClick?: (event: ReactMouseEvent) => void;
|
||||||
onPaneContextMenu?: (event: ReactMouseEvent) => void;
|
onPaneContextMenu?: (event: ReactMouseEvent) => void;
|
||||||
nodeTypes?: NodeTypesType;
|
nodeTypes?: NodeTypes;
|
||||||
edgeTypes?: EdgeTypesType;
|
edgeTypes?: EdgeTypes;
|
||||||
connectionMode?: ConnectionMode;
|
connectionMode?: ConnectionMode;
|
||||||
connectionLineType?: ConnectionLineType;
|
connectionLineType?: ConnectionLineType;
|
||||||
connectionLineStyle?: CSSProperties;
|
connectionLineStyle?: CSSProperties;
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ import { HandleType, StartHandle } from './handles';
|
|||||||
import { DefaultEdgeOptions } from '.';
|
import { DefaultEdgeOptions } from '.';
|
||||||
import { ReactFlowInstance } from './instance';
|
import { ReactFlowInstance } from './instance';
|
||||||
|
|
||||||
export type NodeTypesType = { [key: string]: ReactNode };
|
export type NodeTypes = { [key: string]: ReactNode };
|
||||||
export type EdgeTypesType = NodeTypesType;
|
export type EdgeTypes = NodeTypes;
|
||||||
|
|
||||||
export type FitView = (fitViewOptions?: FitViewOptions) => void;
|
export type FitView = (fitViewOptions?: FitViewOptions) => void;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user