Sampurna
Sampurna

Reputation: 205

State Mutation detected when updating Redux Values

So I'm fairly new to React-Redux and I'm facing this problem where if i update this array with a new object in redux, i'm getting the following error

Uncaught Invariant Violation: A state mutation was detected between dispatches, in the path `settingsObject.arrayForSettings.0.updatedObject`. This may cause incorrect behavior.

The Problem only arises when i update the state in redux with new values, On previous values there is no error. The piece of code that is giving me the error is as follows.

let tempArrayForSettings = [...props.arrayForSettings];
tempArrayForSettings.forEach((element:any) => {
   if(element.settingsType === "DesiredSettingType")
   {
      //modify elements of a JSON object and add it to the element
      element.updatedObject = JSONUpdatedObject;
   }
   //call the action method to update the redux state
   updateAction(tempArrayForSettings);
});

The error is pointing me to the following link : Redux Error

I know I'm not updating the object I'm getting from props instead I'm making a copy using the spread operator so I really don't know why the error is coming whenever I'm firing the updateAction function.

Upvotes: 0

Views: 295

Answers (2)

Itay Elgazar
Itay Elgazar

Reputation: 125

You're updating the object inside the array, so the spread operator that you've created above only clones the array itself, not the objects inside the array. In Javascript, objects are passed by reference (read more here)

To fix this warning, you'd need to copy the object itself, and to do that, you'd need to find the specific object in the array that you'd like to change.

Try this:

const { arrayForSettings } = props;
const modifiedSettings = arrayForSettings.map((element:any) => {
   if(element.settingsType === "DesiredSettingType")
   {
      //modify elements of a JSON object and add it to the element
      return {
        ...element,
        updatedObject: JSONUpdatedObject,
      }

   }
   return element;
}

   updateAction(modifiedSettings);
});

Also, it's recommended that this logic lives on the reducer side, not in your component.

Upvotes: 0

phry
phry

Reputation: 44136

Well, your line element.updatedObject = JSONUpdatedObject; is modifying the object in the Redux store. element is a direct reference to your store object. You would need to do an immutable copy here - your spread above only does a shallow copy, but the items here are still the same.

Generally, you should do logic like this not in your component, but within your Reducer. (see the Style Guide on this topic) That also gives you the benefit that you don't need to care about immutability, as within createSlice reducers you can simply modify data.

Upvotes: 1

Related Questions