import { createSlice } from '@reduxjs/toolkit';
const cartSlice = createSlice({
name: 'cart',
initialState: {
items: [],
},
reducers: {
addToCart: (state, action) => {
state.items.push(action.payload);
},
removeFromCart: (state, action) => {
state.items = state.items.filter(item => item.id !== action.payload.id);
},
clearCart: state => {
state.items = [];
},
},
});
export const { addToCart, removeFromCart, clearCart } = cartSlice.actions;
export default cartSlice.reducer;
It's working while I defined initialstate as array (initialstate =[]) and performing operation (state.push(...)).
The issue here it seems is that you once had a cart slice the likely looked like the following:
const initialState = [];
const cartSlice = createSlice({
name: "cart",
initialState,
reducers: {
addToCart: (state, action) => {
state.push(action.payload);
},
removeFromCart: (state, action) => {
return state.filter((item) => item.id !== action.payload.id);
},
clearCart: (state) => {
return [];
}
}
});
The state this slice/reducer produced was persisted to localStorage.
Example:
"persist:root": "{"cart":"[{\"id\":\"_DX4ebWHrqY1R6iVevCLV\"},{\"id\":\"JTqqLWDHTyCbk4gSroFYX\"}]","_persist":"{\"version\":-1,\"rehydrated\":true}"}"
You then changed the cart slice reducers to generate a different state shape:
const initialState = {
items: []
};
const cartSlice = createSlice({
name: "cart",
initialState,
reducers: {
addToCart: (state, action) => {
state.items.push(action.payload);
},
removeFromCart: (state, action) => {
state.items = state.items.filter((item) => item.id !== action.payload.id);
},
clearCart: (state) => {
state.items = [];
}
}
});
But the previous state shape still exists in localStorage and is rehydrated as the state value, and since there is now a mismatch between the current state value and what the reducers/selectors reference this creates the errors.
If you don't care or need to save the existing state then you can simply delete the persist:root
key/value from localStorage and reload the app. Since there will now be no persisted state to hydrate the app state the initial state from the reducers will compute the initial state tree with the current initial state values.
localStorage
section"persist:root"
entryCreate a migration from the old, incorrect, state to the new current state shape.
import { configureStore, combineReducers } from "@reduxjs/toolkit";
import { createMigrate, persistStore, persistReducer } from "redux-persist";
import storage from "redux-persist/lib/storage";
import cartReducer from "./cart.slice";
const migrations = {
// Move state.cart to state.cart.items
0: (state) => {
const { cart, ...newState } = state;
return {
...newState,
cart: {
items: cart
}
};
}
};
const rootReducer = combineReducers({
cart: cartReducer
auth: authReducer
});
const persistConfig = {
key: "root",
storage,
version: 0, // <-- set state version
migrate: createMigrate(migrations, { debug: true }) // <-- debug true if you want to see logs, otherwise set false
};
const persistedReducer = persistReducer(persistConfig, rootReducer);
const store = configureStore({
reducer: persistedReducer
});
const persistor = persistStore(store);
export { store, persistor };