Reputation: 317
i am getting the following error:
A state mutation was detected between dispatches, in the path 'notifications.adhans.AsrAdhan'. This may cause incorrect behavior. (https://redux.js.org/style-guide/style-guide#do-not-mutate-state)]
Following is my notifications reducer in notifications.ts file.
import {
RESTORE_NOTIFICATIONS,
SET_ADHAN,
SET_ADHANTOGGLE,
SET_REMINDER,
SET_REMINDERTOGGLE,
} from "./../constants";
export const initialState = {
reminderToggle: true,
adhanToggle: true,
adhans: {
FajrAdhan: false,
DhuhrAdhan: true,
AsrAdhan: false, //--->getting mutation error for this
MaghribAdhan: true,
IshaAdhan: true,
},
reminders: {
FajrReminder: false,
DhuhrReminder: false,
AsrReminder: true,
MaghribReminder: false,
IshaReminder: true,
SunriseReminder: true,
MidnightReminder: false,
},
};
export default (state = initialState, action: AnyAction): notificationsT => {
switch (action.type) {
case SET_REMINDERTOGGLE:
return {
...state,
reminderToggle: action.payload,
};
case SET_ADHANTOGGLE:
return {
...state,
adhanToggle: action.payload,
};
case SET_ADHAN:
return {
...state,
adhans: {
...state.adhans,
[action.payload.key]: action.payload.value,
},
};
case SET_REMINDER:
return {
...state,
reminders: {
...state.reminders,
[action.payload.key]: action.payload.value,
},
};
case RESTORE_NOTIFICATIONS:
return { ...action.payload };
default:
return state;
}
};
error stack points at src\screens\Home.tsx:127:14 in RestoreState.
Following is the relevant code for Home.tsx
import AsyncStorage from "@react-native-async-storage/async-storage";
import * as actionTypes from "../store/constants";
import { initialState as notifInitState } from "../store/reducers/notifications";
...
const updatedNotificationsstate = { ...notifInitState };
const adhanKeys = Object.keys(notifInitState.adhans);
const keysArray = [
...adhanKeys,
...//other state keys
];
const Home = ({ navigation }) => {
const dispatch = useAppDispatch();
//When component mounts on start, Restore the redux state
React.useEffect(() => {
const RestoreState = async () => {
const savedState = await AsyncStorage.multiGet(keysArray);
savedState.forEach(([key, value]) => {
...
if(value){
//notifications
if (adhanKeys.includes(key))
return (updatedNotificationsstate.adhans[key] = JSON.parse(value));
...
}
});
dispatch({
type: actionTypes.RESTORE_NOTIFICATIONS,
payload: updatedNotificationsstate,
});
};
RestoreState();
}, []);
---
return (
<Layout>
..
</Layout>
);
};
export default Home;
what am i doing wrong here???
Please note I have removed typesrcipt types for javascript coders convenience.
Upvotes: 2
Views: 318
Reputation: 202916
updatedNotificationsstate.adhans[key] = JSON.parse(value)
looks to be a mutation.
You've correctly created a shallow copy of updatedNotificationsstate
but all the elements are still references to the originals in state, i.e. updatedNotificationsstate.adhans
is a reference to the previous state. You must also shallow copy any nested state properties that are being updated.
if (adhanKeys.includes(key)) {
return (updatedNotificationsstate.adhans = { // <-- new object reference
...updatedNotificationsstate.adhans, // <-- shallow copy previous
[key]: JSON.parse(value) // <-- update property
});
}
Upvotes: 1