Search code examples
reduxreact-reduxreact-hooksstoreredux-toolkit

Redux Persist TypeError: store.dispatch is not a function


While following a tutorial, I got this store.dispatch is not a function error. I've searched stackoverflow for a while, but cannot seem to locate any errors. What am I missing?

Image showing the error [1]: https://i.sstatic.net/AekWH.png

import {configureStore, combineReducers} from '@reduxjs/toolkit'
import cartReducer from './cartRedux'
import userReducer from './userRedux'
import {
  persistStore,
  persistReducer,
  FLUSH,
  REHYDRATE,
  PAUSE,
  PERSIST,
  PURGE,
  REGISTER,
} from 'redux-persist'
import storage from 'redux-persist/lib/storage'

const persistConfig = {
  key: 'root',
  version: 1,
  storage,
}

const rootReducer = combineReducers({user: userReducer, cart: cartReducer})
const persistedReducer = persistReducer(persistConfig, rootReducer)

export const store = () => configureStore({
  reducer: persistedReducer,
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware({
      serializableCheck: {
        ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
      },
    }),
})


export const persistor = persistStore(store)

index

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import {Provider} from 'react-redux'
import {store, persistor} from './redux/store'
import { PersistGate } from 'redux-persist/integration/react'

ReactDOM.render(
  <Provider store={store}>
    <PersistGate loading={null} persistor={persistor}>
      <App />
    </PersistGate>
  </Provider>,
  document.getElementById('root')
);

Solution

  • It seems you declared your store to be a function that returns a configured store.

    export const store = () => configureStore({ // <-- a function
      reducer: persistedReducer,
      middleware: (getDefaultMiddleware) =>
        getDefaultMiddleware({
          serializableCheck: {
            ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
          },
        }),
    })
    

    and you pass a reference to this store function persistStore

    export const persistor = persistStore(store) // <-- store not invoked
    

    While you could just invoke the store function each place this would be bad since you'd effectively create multiple store instances in different parts of your app that won't work together. You should just export and consume an already configured store object.

    export const store = configureStore({
      reducer: persistedReducer,
      middleware: (getDefaultMiddleware) =>
        getDefaultMiddleware({
          serializableCheck: {
            ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
          },
        }),
    });
    
    export const persistor = persistStore(store);