Search code examples
javascriptreactjsreduxreact-reduxredux-thunk

React/Redux - Add element instead of replacing state


I am using https://reactflow.dev/ library and in Redux state when I add a new element rather than add it to the array it replaces the previous item with a new one. enter image description here

Reducer

import * as types from '../actions/types';

const initialState = {
  elements: [],
  currentElement: undefined,
};

const flow = (state = initialState, action) => {
  switch (action.type) {
    case types.ADD_ELEMENT:
      return {
        ...initialState,
        elements: initialState.elements.concat(action.payload),
        // elements: [...initialState.elements, action.payload],
      };
  }
}

Action

import { ADD_ELEMENT } from './types';

export const addElement = (node) => (dispatch) => {
  dispatch({
    type: ADD_ELEMENT,
    payload: node,
  });
};

DndFLow

const onDrop = (event) => {
    event.preventDefault();

    const reactFlowBounds = reactFlowWrapper.current.getBoundingClientRect();
    const type = event.dataTransfer.getData('application/reactflow');
    const position = reactFlowInstance.project({
      x: event.clientX - reactFlowBounds.left,
      y: event.clientY - reactFlowBounds.top,
    });

    const newNode = {
      id: getId(),
      type,
      position,
      data: { label: `${type}` },
    };

    addElement(newNode);
    setElements((es) => es.concat(newNode));
  };

Solution

  • You're using initialState in the reducer, instead of the state.

    Using the state might fix your issue:

    const flow = (state = initialState, action) => {
      switch (action.type) {
        case types.ADD_ELEMENT:
          return {
            ...state,
            elements: state.elements.concat(action.payload),
          };
      }
    }
    

    The state = initialState is correct since that means it will use the initialState by default if state doesn't have any value otherwise, but you shouldn't use the initialState beyond that, unless you want to reset your state to it.