refactor(wrapEdge): remove unnecessary memoization
This commit is contained in:
@@ -9,7 +9,6 @@ import ReactFlow, {
|
||||
MarkerType,
|
||||
MiniMap,
|
||||
Node,
|
||||
Position,
|
||||
ReactFlowInstance,
|
||||
useEdgesState,
|
||||
useNodesState,
|
||||
@@ -20,6 +19,11 @@ import CustomEdge2 from './CustomEdge2';
|
||||
const onInit = (reactFlowInstance: ReactFlowInstance) => reactFlowInstance.fitView();
|
||||
const onNodeDragStop = (_: MouseEvent, node: Node) => console.log('drag stop', node);
|
||||
const onNodeClick = (_: MouseEvent, node: Node) => console.log('click', node);
|
||||
const onEdgeClick = (_: MouseEvent, edge: Edge) => console.log('click', edge);
|
||||
const onEdgeDoubleClick = (_: MouseEvent, edge: Edge) => console.log('dblclick', edge);
|
||||
const onEdgeMouseEnter = (_: MouseEvent, edge: Edge) => console.log('enter', edge);
|
||||
const onEdgeMouseMove = (_: MouseEvent, edge: Edge) => console.log('move', edge);
|
||||
const onEdgeMouseLeave = (_: MouseEvent, edge: Edge) => console.log('leave', edge);
|
||||
|
||||
const initialNodes: Node[] = [
|
||||
{ id: '1', type: 'input', data: { label: 'Input 1' }, position: { x: 250, y: 0 } },
|
||||
@@ -131,6 +135,11 @@ const EdgesFlow = () => {
|
||||
onInit={onInit}
|
||||
snapToGrid={true}
|
||||
edgeTypes={edgeTypes}
|
||||
onEdgeClick={onEdgeClick}
|
||||
onEdgeDoubleClick={onEdgeDoubleClick}
|
||||
onEdgeMouseEnter={onEdgeMouseEnter}
|
||||
onEdgeMouseMove={onEdgeMouseMove}
|
||||
onEdgeMouseLeave={onEdgeMouseLeave}
|
||||
>
|
||||
<MiniMap />
|
||||
<Controls />
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import { MarkerType, Position } from '../../types';
|
||||
import { MouseEvent as ReactMouseEvent } from 'react';
|
||||
import { GetState } from 'zustand';
|
||||
|
||||
import { Edge, MarkerType, Position, ReactFlowState } from '../../types';
|
||||
|
||||
export const getMarkerEnd = (markerType?: MarkerType, markerEndId?: string): string => {
|
||||
if (typeof markerEndId !== 'undefined' && markerEndId) {
|
||||
@@ -52,3 +55,16 @@ export const getCenter = ({
|
||||
|
||||
return [centerX, centerY, xOffset, yOffset];
|
||||
};
|
||||
|
||||
export function getMouseHandler(
|
||||
id: string,
|
||||
getState: GetState<ReactFlowState>,
|
||||
handler?: (event: ReactMouseEvent<SVGGElement, MouseEvent>, edge: Edge) => void
|
||||
) {
|
||||
return handler === undefined
|
||||
? handler
|
||||
: (event: ReactMouseEvent<SVGGElement, MouseEvent>) => {
|
||||
const edge = getState().edges.find((e) => e.id === id)!;
|
||||
handler(event, { ...edge });
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import React, { memo, ComponentType, useCallback, useState, useMemo } from 'react';
|
||||
import React, { memo, ComponentType, useState, useMemo } from 'react';
|
||||
import cc from 'classcat';
|
||||
import shallow from 'zustand/shallow';
|
||||
|
||||
import { useStore, useStoreApi } from '../../store';
|
||||
import { Edge, EdgeProps, WrapEdgeProps, ReactFlowState, Connection } from '../../types';
|
||||
import { EdgeProps, WrapEdgeProps, ReactFlowState, Connection } from '../../types';
|
||||
import { handleMouseDown } from '../../components/Handle/handler';
|
||||
import { EdgeAnchor } from './EdgeAnchor';
|
||||
import { getMarkerId } from '../../utils/graph';
|
||||
import { getMouseHandler } from './utils';
|
||||
|
||||
const selector = (s: ReactFlowState) => ({
|
||||
addSelectedEdges: s.addSelectedEdges,
|
||||
@@ -53,10 +54,78 @@ export default (EdgeComponent: ComponentType<EdgeProps>) => {
|
||||
markerEnd,
|
||||
markerStart,
|
||||
}: WrapEdgeProps): JSX.Element | null => {
|
||||
const store = useStoreApi();
|
||||
const { addSelectedEdges, connectionMode } = useStore(selector, shallow);
|
||||
|
||||
const [updating, setUpdating] = useState<boolean>(false);
|
||||
const { addSelectedEdges, connectionMode } = useStore(selector, shallow);
|
||||
const store = useStoreApi();
|
||||
|
||||
const onEdgeClick = (event: React.MouseEvent<SVGGElement, MouseEvent>): void => {
|
||||
const edge = store.getState().edges.find((e) => e.id === id)!;
|
||||
|
||||
if (elementsSelectable) {
|
||||
store.setState({ nodesSelectionActive: false });
|
||||
addSelectedEdges([id]);
|
||||
}
|
||||
|
||||
onClick?.(event, edge);
|
||||
};
|
||||
|
||||
const onEdgeDoubleClickHandler = getMouseHandler(id, store.getState, onEdgeDoubleClick);
|
||||
const onEdgeContextMenu = getMouseHandler(id, store.getState, onContextMenu);
|
||||
const onEdgeMouseEnter = getMouseHandler(id, store.getState, onMouseEnter);
|
||||
const onEdgeMouseMove = getMouseHandler(id, store.getState, onMouseMove);
|
||||
const onEdgeMouseLeave = getMouseHandler(id, store.getState, onMouseLeave);
|
||||
|
||||
const handleEdgeUpdater = (event: React.MouseEvent<SVGGElement, MouseEvent>, isSourceHandle: boolean) => {
|
||||
const nodeId = isSourceHandle ? target : source;
|
||||
const handleId = (isSourceHandle ? targetHandleId : sourceHandleId) || null;
|
||||
const handleType = isSourceHandle ? 'target' : 'source';
|
||||
const isValidConnection = () => true;
|
||||
const isTarget = isSourceHandle;
|
||||
const edge = store.getState().edges.find((e) => e.id === id)!;
|
||||
|
||||
onEdgeUpdateStart?.(event, edge, handleType);
|
||||
|
||||
const _onEdgeUpdate = onEdgeUpdateEnd
|
||||
? (evt: MouseEvent): void => onEdgeUpdateEnd(evt, edge, handleType)
|
||||
: undefined;
|
||||
|
||||
const onConnectEdge = (connection: Connection) => {
|
||||
const { edges } = store.getState();
|
||||
const edge = edges.find((e) => e.id === id);
|
||||
|
||||
if (edge && onEdgeUpdate) {
|
||||
onEdgeUpdate(edge, connection);
|
||||
}
|
||||
};
|
||||
|
||||
handleMouseDown(
|
||||
event,
|
||||
handleId,
|
||||
nodeId,
|
||||
store.setState,
|
||||
onConnectEdge,
|
||||
isTarget,
|
||||
isValidConnection,
|
||||
connectionMode,
|
||||
handleType,
|
||||
_onEdgeUpdate,
|
||||
store.getState
|
||||
);
|
||||
};
|
||||
|
||||
const onEdgeUpdaterSourceMouseDown = (event: React.MouseEvent<SVGGElement, MouseEvent>): void =>
|
||||
handleEdgeUpdater(event, true);
|
||||
const onEdgeUpdaterTargetMouseDown = (event: React.MouseEvent<SVGGElement, MouseEvent>): void =>
|
||||
handleEdgeUpdater(event, false);
|
||||
|
||||
const onEdgeUpdaterMouseEnter = () => setUpdating(true);
|
||||
const onEdgeUpdaterMouseOut = () => setUpdating(false);
|
||||
const markerStartUrl = useMemo(() => `url(#${getMarkerId(markerStart)})`, [markerStart]);
|
||||
const markerEndUrl = useMemo(() => `url(#${getMarkerId(markerEnd)})`, [markerEnd]);
|
||||
|
||||
if (hidden) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const inactive = !elementsSelectable && !onClick;
|
||||
const handleEdgeUpdate = typeof onEdgeUpdate !== 'undefined';
|
||||
@@ -67,139 +136,6 @@ export default (EdgeComponent: ComponentType<EdgeProps>) => {
|
||||
{ selected, animated, inactive, updating },
|
||||
]);
|
||||
|
||||
const edgeElement = useMemo<Edge>(() => {
|
||||
const el: Edge = {
|
||||
id,
|
||||
source,
|
||||
target,
|
||||
type,
|
||||
};
|
||||
|
||||
if (sourceHandleId) {
|
||||
el.sourceHandle = sourceHandleId;
|
||||
}
|
||||
|
||||
if (targetHandleId) {
|
||||
el.targetHandle = targetHandleId;
|
||||
}
|
||||
|
||||
if (typeof data !== 'undefined') {
|
||||
el.data = data;
|
||||
}
|
||||
|
||||
return el;
|
||||
}, [id, source, target, type, sourceHandleId, targetHandleId, data]);
|
||||
|
||||
const onEdgeClick = useCallback(
|
||||
(event: React.MouseEvent<SVGGElement, MouseEvent>): void => {
|
||||
if (elementsSelectable) {
|
||||
store.setState({ nodesSelectionActive: false });
|
||||
addSelectedEdges([edgeElement.id]);
|
||||
}
|
||||
|
||||
onClick?.(event, edgeElement);
|
||||
},
|
||||
[elementsSelectable, edgeElement, onClick]
|
||||
);
|
||||
|
||||
const onEdgeDoubleClickHandler = useCallback(
|
||||
(event: React.MouseEvent<SVGGElement, MouseEvent>) => {
|
||||
onEdgeDoubleClick?.(event, edgeElement);
|
||||
},
|
||||
[edgeElement, onEdgeDoubleClick]
|
||||
);
|
||||
|
||||
const onEdgeContextMenu = useCallback(
|
||||
(event: React.MouseEvent<SVGGElement, MouseEvent>): void => {
|
||||
onContextMenu?.(event, edgeElement);
|
||||
},
|
||||
[edgeElement, onContextMenu]
|
||||
);
|
||||
|
||||
const onEdgeMouseEnter = useCallback(
|
||||
(event: React.MouseEvent<SVGGElement, MouseEvent>): void => {
|
||||
onMouseEnter?.(event, edgeElement);
|
||||
},
|
||||
[edgeElement, onContextMenu]
|
||||
);
|
||||
|
||||
const onEdgeMouseMove = useCallback(
|
||||
(event: React.MouseEvent<SVGGElement, MouseEvent>): void => {
|
||||
onMouseMove?.(event, edgeElement);
|
||||
},
|
||||
[edgeElement, onContextMenu]
|
||||
);
|
||||
|
||||
const onEdgeMouseLeave = useCallback(
|
||||
(event: React.MouseEvent<SVGGElement, MouseEvent>): void => {
|
||||
onMouseLeave?.(event, edgeElement);
|
||||
},
|
||||
[edgeElement, onContextMenu]
|
||||
);
|
||||
|
||||
const handleEdgeUpdater = useCallback(
|
||||
(event: React.MouseEvent<SVGGElement, MouseEvent>, isSourceHandle: boolean) => {
|
||||
const nodeId = isSourceHandle ? target : source;
|
||||
const handleId = (isSourceHandle ? targetHandleId : sourceHandleId) || null;
|
||||
const handleType = isSourceHandle ? 'target' : 'source';
|
||||
const isValidConnection = () => true;
|
||||
const isTarget = isSourceHandle;
|
||||
|
||||
onEdgeUpdateStart?.(event, edgeElement, handleType);
|
||||
|
||||
const _onEdgeUpdate = onEdgeUpdateEnd
|
||||
? (evt: MouseEvent): void => onEdgeUpdateEnd(evt, edgeElement, handleType)
|
||||
: undefined;
|
||||
|
||||
const onConnectEdge = (connection: Connection) => {
|
||||
const { edges } = store.getState();
|
||||
const edge = edges.find((e) => e.id === id);
|
||||
|
||||
if (edge && onEdgeUpdate) {
|
||||
onEdgeUpdate(edge, connection);
|
||||
}
|
||||
};
|
||||
|
||||
handleMouseDown(
|
||||
event,
|
||||
handleId,
|
||||
nodeId,
|
||||
store.setState,
|
||||
onConnectEdge,
|
||||
isTarget,
|
||||
isValidConnection,
|
||||
connectionMode,
|
||||
handleType,
|
||||
_onEdgeUpdate,
|
||||
store.getState
|
||||
);
|
||||
},
|
||||
[id, source, target, type, sourceHandleId, targetHandleId, edgeElement, onEdgeUpdate]
|
||||
);
|
||||
|
||||
const onEdgeUpdaterSourceMouseDown = useCallback(
|
||||
(event: React.MouseEvent<SVGGElement, MouseEvent>): void => {
|
||||
handleEdgeUpdater(event, true);
|
||||
},
|
||||
[id, source, sourceHandleId, handleEdgeUpdater]
|
||||
);
|
||||
|
||||
const onEdgeUpdaterTargetMouseDown = useCallback(
|
||||
(event: React.MouseEvent<SVGGElement, MouseEvent>): void => {
|
||||
handleEdgeUpdater(event, false);
|
||||
},
|
||||
[id, target, targetHandleId, handleEdgeUpdater]
|
||||
);
|
||||
|
||||
const onEdgeUpdaterMouseEnter = useCallback(() => setUpdating(true), [setUpdating]);
|
||||
const onEdgeUpdaterMouseOut = useCallback(() => setUpdating(false), [setUpdating]);
|
||||
const markerStartUrl = useMemo(() => `url(#${getMarkerId(markerStart)})`, [markerStart]);
|
||||
const markerEndUrl = useMemo(() => `url(#${getMarkerId(markerEnd)})`, [markerEnd]);
|
||||
|
||||
if (hidden) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<g
|
||||
className={edgeClasses}
|
||||
|
||||
Reference in New Issue
Block a user