refactor(nodeTypes/edgeTypes): show warning when not memoized closes #1620
This commit is contained in:
@@ -5,7 +5,7 @@ import wrapEdge from '../../components/Edges/wrapEdge';
|
||||
import { rectToBox } from '../../utils';
|
||||
|
||||
import {
|
||||
EdgeTypesType,
|
||||
EdgeTypes,
|
||||
EdgeProps,
|
||||
HandleElement,
|
||||
Position,
|
||||
@@ -16,16 +16,18 @@ import {
|
||||
NodeHandleBounds,
|
||||
} from '../../types';
|
||||
|
||||
export function createEdgeTypes(edgeTypes: EdgeTypesType): EdgeTypesType {
|
||||
const standardTypes: EdgeTypesType = {
|
||||
export type CreateEdgeTypes = (edgeTypes: EdgeTypes) => EdgeTypes;
|
||||
|
||||
export function createEdgeTypes(edgeTypes: EdgeTypes): EdgeTypes {
|
||||
const standardTypes: EdgeTypes = {
|
||||
default: wrapEdge((edgeTypes.default || BezierEdge) as ComponentType<EdgeProps>),
|
||||
straight: wrapEdge((edgeTypes.bezier || StraightEdge) as ComponentType<EdgeProps>),
|
||||
step: wrapEdge((edgeTypes.step || StepEdge) as ComponentType<EdgeProps>),
|
||||
smoothstep: wrapEdge((edgeTypes.step || SmoothStepEdge) as ComponentType<EdgeProps>),
|
||||
};
|
||||
|
||||
const wrappedTypes = {} as EdgeTypesType;
|
||||
const specialTypes: EdgeTypesType = Object.keys(edgeTypes)
|
||||
const wrappedTypes = {} as EdgeTypes;
|
||||
const specialTypes: EdgeTypes = Object.keys(edgeTypes)
|
||||
.filter((k) => !['default', 'bezier'].includes(k))
|
||||
.reduce((res, key) => {
|
||||
res[key] = wrapEdge((edgeTypes[key] || BezierEdge) as ComponentType<EdgeProps>);
|
||||
|
||||
@@ -5,11 +5,11 @@ import NodeRenderer from '../NodeRenderer';
|
||||
import EdgeRenderer from '../EdgeRenderer';
|
||||
import Viewport from '../Viewport';
|
||||
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'> {
|
||||
nodeTypes: NodeTypesType;
|
||||
edgeTypes: EdgeTypesType;
|
||||
nodeTypes: NodeTypes;
|
||||
edgeTypes: EdgeTypes;
|
||||
selectionKeyCode: KeyCode;
|
||||
deleteKeyCode: KeyCode;
|
||||
multiSelectionKeyCode: KeyCode;
|
||||
|
||||
@@ -3,10 +3,10 @@ import shallow from 'zustand/shallow';
|
||||
|
||||
import useVisibleNodes from '../../hooks/useVisibleNodes';
|
||||
import { useStore } from '../../store';
|
||||
import { Node, NodeTypesType, Position, ReactFlowState, WrapNodeProps } from '../../types';
|
||||
import { Node, NodeTypes, Position, ReactFlowState, WrapNodeProps } from '../../types';
|
||||
|
||||
interface NodeRendererProps {
|
||||
nodeTypes: NodeTypesType;
|
||||
nodeTypes: NodeTypes;
|
||||
selectNodesOnDrag: boolean;
|
||||
onNodeClick?: (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 GroupNode from '../../components/Nodes/GroupNode';
|
||||
import wrapNode from '../../components/Nodes/wrapNode';
|
||||
import { NodeTypesType, NodeProps } from '../../types';
|
||||
import { NodeTypes, NodeProps } from '../../types';
|
||||
|
||||
export function createNodeTypes(nodeTypes: NodeTypesType): NodeTypesType {
|
||||
const standardTypes: NodeTypesType = {
|
||||
export type CreateNodeTypes = (nodeTypes: NodeTypes) => NodeTypes;
|
||||
|
||||
export function createNodeTypes(nodeTypes: NodeTypes): NodeTypes {
|
||||
const standardTypes: NodeTypes = {
|
||||
input: wrapNode((nodeTypes.input || InputNode) as ComponentType<NodeProps>),
|
||||
default: wrapNode((nodeTypes.default || DefaultNode) as ComponentType<NodeProps>),
|
||||
output: wrapNode((nodeTypes.output || OutputNode) as ComponentType<NodeProps>),
|
||||
group: wrapNode((nodeTypes.group || GroupNode) as ComponentType<NodeProps>),
|
||||
};
|
||||
|
||||
const wrappedTypes = {} as NodeTypesType;
|
||||
const specialTypes: NodeTypesType = Object.keys(nodeTypes)
|
||||
const wrappedTypes = {} as NodeTypes;
|
||||
const specialTypes: NodeTypes = Object.keys(nodeTypes)
|
||||
.filter((k) => !['input', 'default', 'output', 'group'].includes(k))
|
||||
.reduce((res, key) => {
|
||||
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 GraphView from '../GraphView';
|
||||
@@ -13,10 +13,19 @@ import Attribution from '../../components/Attribution';
|
||||
import { createEdgeTypes } from '../EdgeRenderer/utils';
|
||||
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 '../../theme-default.css';
|
||||
import { useNodeOrEdgeTypes } from './utils';
|
||||
|
||||
const defaultNodeTypes = {
|
||||
input: InputNode,
|
||||
@@ -127,8 +136,8 @@ const ReactFlow = forwardRef<ReactFlowRefType, ReactFlowProps>(
|
||||
},
|
||||
ref
|
||||
) => {
|
||||
const nodeTypesParsed = useMemo(() => createNodeTypes(nodeTypes), [nodeTypes]);
|
||||
const edgeTypesParsed = useMemo(() => createEdgeTypes(edgeTypes), [edgeTypes]);
|
||||
const nodeTypesParsed = useNodeOrEdgeTypes(nodeTypes, createNodeTypes) as NodeTypes;
|
||||
const edgeTypesParsed = useNodeOrEdgeTypes(edgeTypes, createEdgeTypes) as EdgeTypes;
|
||||
const reactFlowClasses = cc(['react-flow', className]);
|
||||
|
||||
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;
|
||||
}
|
||||
Reference in New Issue
Block a user