Persistent shopping basket using Redux Toolkit in an online store application

I’m working on an online store and need help keeping the items in the cart even when users refresh the page. I’ve set up a Redux slice for managing the cart state. I’ve heard about redux-toolkit-persist and think it might solve my problem. Here’s a simplified version of my cart slice:

import { createSlice } from '@reduxjs/toolkit'

const cartSlice = createSlice({
  name: 'basket',
  initialState: { items: [], isOpen: false },
  reducers: {
    addItem: (state, action) => {
      state.items.push(action.payload)
    },
    removeItem: (state, action) => {
      state.items = state.items.filter(item => item.id !== action.payload)
    },
    updateQuantity: (state, action) => {
      const { id, change } = action.payload
      const item = state.items.find(item => item.id === id)
      if (item) item.quantity += change
    },
    toggleBasket: state => {
      state.isOpen = !state.isOpen
    }
  }
})

export const { addItem, removeItem, updateQuantity, toggleBasket } = cartSlice.actions
export default cartSlice.reducer

I also have a ProductCard component that handles adding items to the cart. How can I make the cart state persist across page reloads?

I’ve encountered a similar issue in my e-commerce projects. While localStorage is a viable option, Redux Persist offers a more robust solution for your needs. It seamlessly integrates with Redux Toolkit and handles state rehydration automatically.

To implement it, first install the package:

npm install redux-persist

Then, modify your store configuration:

import { configureStore } from ‘@reduxjs/toolkit’
import { persistStore, persistReducer } from ‘redux-persist’
import storage from ‘redux-persist/lib/storage’
import cartReducer from ‘./cartSlice’

const persistConfig = {
key: ‘root’,
storage,
}

const persistedReducer = persistReducer(persistConfig, cartReducer)

export const store = configureStore({
reducer: {
cart: persistedReducer,
},
})

export const persistor = persistStore(store)

Wrap your app with PersistGate from redux-persist, and you’re set. This approach ensures your cart state persists across page reloads without manual intervention.

hey Sky_Dreamer! i’ve used redux-toolkit-persist before and it works great for this. just install it with npm, wrap ur app with PersistGate, and update ur store config. it’ll handle everything automagically. no need to mess with localStorage or anything. lemme know if u need more help setting it up!

Hey Sky_Dreamer! :wave: That’s a cool project you’re working on! I’ve actually been tinkering with something similar recently.

Have you considered using localStorage to persist your cart data? It’s a bit more lightweight than redux-persist and might be easier to set up. You could save the cart state to localStorage whenever it changes, and then load it back into Redux when the page loads.

Something like this might work:

// In your cartSlice
const loadCartState = () => {
  try {
    const serializedState = localStorage.getItem('cartState');
    if (serializedState === null) {
      return undefined;
    }
    return JSON.parse(serializedState);
  } catch (err) {
    return undefined;
  }
};

const saveCartState = (state) => {
  try {
    const serializedState = JSON.stringify(state);
    localStorage.setItem('cartState', serializedState);
  } catch {
    // Ignore write errors
  }
};

// Then in your store setup
const store = configureStore({
  reducer: {
    cart: cartSlice.reducer,
    // other reducers...
  },
  preloadedState: {
    cart: loadCartState(),
  },
});

store.subscribe(() => {
  saveCartState(store.getState().cart);
});

What do you think? Have you tried anything like this before? I’m curious to hear how it goes if you give it a shot!