refactor(reducer): only iterate incoming elements once

This commit is contained in:
moklick
2021-02-14 14:52:39 +01:00
parent acd6b76b14
commit 5aa78cf2fc
+26 -33
View File
@@ -18,45 +18,36 @@ import { ReactFlowAction } from './actions';
import { initialState } from './index'; import { initialState } from './index';
type ElementsSplitted = { type NextElements = {
nodeElements: Node[]; nextNodes: Node[];
edgeElements: Edge[]; nextEdges: Edge[];
}; };
export default function reactFlowReducer(state = initialState, action: ReactFlowAction): ReactFlowState { export default function reactFlowReducer(state = initialState, action: ReactFlowAction): ReactFlowState {
switch (action.type) { switch (action.type) {
case constants.SET_ELEMENTS: { case constants.SET_ELEMENTS: {
const propElements = action.payload; const propElements = action.payload;
const elementsSplitted: ElementsSplitted = { const nextElements: NextElements = {
nodeElements: [], nextNodes: [],
edgeElements: [], nextEdges: [],
}; };
const { nodeElements, edgeElements } = propElements.reduce((res, item): ElementsSplitted => { const { nextNodes, nextEdges } = propElements.reduce((res, propElement): NextElements => {
if (isNode(item)) { if (isNode(propElement)) {
res.nodeElements.push(item); let storeNode = state.nodes.find((node) => node.id === propElement.id);
} else if (isEdge(item)) {
res.edgeElements.push(item);
}
return res;
}, elementsSplitted);
const nextNodes = nodeElements.map((propNode: Node) => {
let storeNode = state.nodes.find((node) => node.id === propNode.id);
// update existing element // update existing element
if (storeNode) { if (storeNode) {
const positionChanged = const positionChanged =
storeNode.position.x !== propNode.position.x || storeNode.position.y !== propNode.position.y; storeNode.position.x !== propElement.position.x || storeNode.position.y !== propElement.position.y;
const typeChanged = typeof propNode.type !== 'undefined' && propNode.type !== storeNode.type; const typeChanged = typeof propElement.type !== 'undefined' && propElement.type !== storeNode.type;
storeNode = { storeNode = {
...storeNode, ...storeNode,
...propNode, ...propElement,
}; };
if (positionChanged) { if (positionChanged) {
storeNode.__rf.position = propNode.position; storeNode.__rf.position = propElement.position;
} }
if (typeChanged) { if (typeChanged) {
@@ -65,25 +56,28 @@ export default function reactFlowReducer(state = initialState, action: ReactFlow
storeNode.__rf.width = null; storeNode.__rf.width = null;
} }
return storeNode; res.nextNodes.push(storeNode);
} else { } else {
// add new element // add new element
return parseNode(propNode, state.nodeExtent); res.nextNodes.push(parseNode(propElement, state.nodeExtent));
} }
}); } else if (isEdge(propElement)) {
let storeEdge = state.edges.find((se) => se.id === propElement.id);
const nextEdges = edgeElements.map((propEdge: Edge) => {
let storeEdge = state.edges.find((se) => se.id === propEdge.id);
if (storeEdge) { if (storeEdge) {
return { storeEdge = {
...storeEdge, ...storeEdge,
...propEdge, ...propElement,
}; };
res.nextEdges.push(storeEdge);
} else { } else {
return parseEdge(propEdge); res.nextEdges.push(parseEdge(propElement));
} }
}); }
return res;
}, nextElements);
return { ...state, nodes: nextNodes, edges: nextEdges }; return { ...state, nodes: nextNodes, edges: nextEdges };
} }
@@ -121,7 +115,6 @@ export default function reactFlowReducer(state = initialState, action: ReactFlow
} }
case constants.UPDATE_NODE_POS: { case constants.UPDATE_NODE_POS: {
const { id, pos } = action.payload; const { id, pos } = action.payload;
let position: XYPosition = pos; let position: XYPosition = pos;
if (state.snapToGrid) { if (state.snapToGrid) {