reactjsreact-reduxredux-toolkitredux-persist

Uncaught TypeError: Cannot destructure property 'cart' of '(0 , react_redux__WEBPACK_IMPORTED_MODULE_3__.useSelector)(...)' as it is undefined


I am getting above error while using useSelecor() to get state value from redux. Got this error while i applied react-persist.

error line :- const { cart } = useSelector(state => state.cart);

Here is the code for store.js

import { configureStore } from "@reduxjs/toolkit";
     import CartSlice from "./CartSlice";
     import storage from 'redux-persist/lib/storage';
     import { persistReducer, persistStore } from "redux-persist";

     const persistConfig = {
         key: 'root',
         storage,
     };

     const persistedReducer = persistReducer(persistConfig, CartSlice);

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

     export default persistStore(store);

Solution

  • Well, you didn't set up the RTK with redux-persist correctly. The error message means the state.cart is undefined and can't destructure property cart of undefined.

    The second parameter of persistReducer function is a reducer function, but you passed a state slice which returned by createSlice() API I guess.

    The below example will persist cart state in local storage:

    import React from 'react';
    import ReactDOM from 'react-dom/client';
    import App from './App';
    
    import { configureStore, createSlice } from '@reduxjs/toolkit';
    import storage from 'redux-persist/lib/storage';
    import { persistReducer, persistStore, PURGE, REGISTER, REHYDRATE, FLUSH, PAUSE, PERSIST } from 'redux-persist';
    import { Provider } from 'react-redux';
    import { PersistGate } from 'redux-persist/integration/react';
    
    const cartSlice = createSlice({
        name: 'cart',
        initialState: {
            cart: {
                items: [1, 2, 3],
            },
        },
        reducers: {},
    });
    
    const cartPersistConfig = {
        key: 'cart',
        storage,
    };
    
    const store = configureStore({
        reducer: {
            cart: persistReducer(cartPersistConfig, cartSlice.reducer),
        },
        middleware: (getDefaultMiddleware) =>
            getDefaultMiddleware({
                serializableCheck: {
                    ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
                },
            }),
    });
    
    const persistor = persistStore(store);
    
    const rootElement = document.getElementById('root')!;
    const root = ReactDOM.createRoot(rootElement);
    
    root.render(
        <Provider store={store}>
            <PersistGate loading={<p>loading state...</p>} persistor={persistor}>
                <App />
            </PersistGate>
        </Provider>,
    );
    
    localStorage.getItem('persist:cart') 
    // {"cart":"{\"items\":[1,2,3]}","_persist":"{\"version\":-1,\"rehydrated\":true}"}
    

    codesandbox

    Further reading: Use with Redux-Persist