简体   繁体   中英

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.

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM