Search code examples
reactjsredux

Why redux losing it new value when pushing a new value into the redux array and refreshing even though redux-persist is there?


I am using redux for state management in my app.

const addStepReducer = (
  stepDetails = [
    {
      stepId: "001",
      stepTitle: "Step Name",
      stepDescription:"Step Desc",
    },
  ],
  action
) => {
   if (action.type === "ADD_STEP") {
    stepDetails.push(action.payload);
    
  }
  

  return stepDetails;
};

The above code is my reducer function.

But when I reload the page the stepDetails will be populated with the default value only, the new value pushed will be gone. But other redux stores persists its value after reloading.

I don't understand why redux is behaving in this way. But I know one thing instead of pushing if we used assigning a value it will persist i.e. stepDetails=action.payload;(This is possible if we need just the payload only but in my case i need the array itself). Please let me know if anyone knows about this issue.


Solution

  • You cannot use mutating logic like that if you decide to write Redux in the pre-2019 legacy style like you are doing.

    Generally, the recommendation would be that you follow the official tutorial and learn modern Redux.

    In modern Redux, your code would look like this and you would be allowed to use .push

    import { createSlice } from '@reduxjs/toolkit'
    const stepSlice = createSlice({
      name: "stepDetails",
      initialState: [
        {
          stepId: "001",
          stepTitle: "Step Name",
          stepDescription:"Step Desc",
        },
      ],
      reducers: {
        addStep(state, action) {
          state.push(action.payload)
        }
      }
    })
    export const { addStep } = stepSlice.actions
    const addStepReducer = stepSlice.reducer
    

    In the legacy Redux reducer you are writing here, you're not allowed to write mutable functions like .push and instead of

    stepDetails.push(action.payload);
    

    you'd have to do

    return [...stepDetails, action.payload]
    

    instead.