You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Redux Toolkit与createAsyncThunk时出现baseReducer非函数错误

问题:Redux-Persist 抛出 "baseReducer is not a function" 错误

我使用 Redux-Toolkit 从 MSAL 获取 accessToken,并用 Redux-Persist 将 Store 持久化到 localStorage。客户端列表页可正常获取搜索结果,此前页面刷新也无异常,但近期突然抛出错误:

Error in function eval in ./node_modules/redux-persist/es/persistReducer.js:144 baseReducer is not a function

相关代码如下:


store.js

import { configureStore } from '@reduxjs/toolkit'
import usersReducer from "./userSlice";
import storage from 'redux-persist/lib/storage';
import { persistReducer, persistStore } from 'redux-persist';
const persistConfig = { key: 'root', storage, }
const persistedReducer = persistReducer(persistConfig, usersReducer)
export const store = configureStore(
  { 
    reducer: { 
      users: persistedReducer,
    }
  })
export const persistor = persistStore(store)

userSlice.js

import { useMsal } from "@azure/msal-react";
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
import { loginRequest } from "./authConfig";
import { msalInstance } from "./pages/index";

export const fetchUsersToken = createAsyncThunk(
  "users/fetchUsersToken",
  async (dispatch, getState) => {
    try {
      const token = await msalInstance.acquireTokenSilent(dispatch)
        .then((data) => data.accessToken)
      return token
    } catch (error) {
      return error.response.data
    }
  }
);

const usersSlice = createSlice({
  name: "users",
  initialState: {
    users: null,
    loading: true
  },
  reducers: {},
  extraReducers(builder) {
    builder
      .addCase(fetchUsersToken.pending, (state, action) => {
        state.loading = true
      })
      .addCase(fetchUsersToken.fulfilled, (state, action) => {
        state.loading = false,
        state.users = action.payload
      })
      .addCase(fetchUsersToken.rejected, (state, action) => {
        state.loading = false

      });
  }
})

export default usersSlice.reducer;

Layout 组件 index.js

import React from "react"
import { Provider, useDispatch } from "react-redux";
import {persistor, store} from "../../store";
import Footer from "../Footer"
import { createTheme, ThemeProvider } from "@mui/material/styles"
import { PersistGate } from 'redux-persist/integration/react';

const theme = createTheme({
  palette: {
    primary: { main: "#000000" },
  },
})

const Layout = ({ children }) => (
  <div>
    <ThemeProvider theme={theme}>
      <Provider store={store}>
        <PersistGate loading={null} persistor={persistor}>
          {children}
          <Footer/>
        </PersistGate>
      </Provider>
    </ThemeProvider>
  </div>
)

export default Layout

LandingPage.js(分发 action 处)

const request = {
  ...loginRequest,
  account: accounts[0]
}
store.dispatch(fetchUsersToken(request))

MSAL 初始化 index.js

import React from "react"
import { Helmet } from "react-helmet"
import { PublicClientApplication } from "@azure/msal-browser"
import { MsalProvider, useMsal } from "@azure/msal-react"
import { loginRequest, msalConfig } from "../authConfig"
import PageLayout from "../components/PageLayout"
import App from "./app"
import Layout from "../components/Layout"

import { Provider, useDispatch } from "react-redux";
import {store} from "../store";

export const msalInstance = new PublicClientApplication(msalConfig)

export default function Home() {

return (
<>
  <Helmet>
    <title>Client Engagement Lookup</title>
  </Helmet>
  <MsalProvider instance={msalInstance}>
    
       <Layout>
      <PageLayout />
      </Layout>

  </MsalProvider>
 </>
 )
}

问题排查与修复

1. AsyncThunk 参数定义错误

fetchUsersToken 的参数顺序完全写反了:createAsyncThunk 的 payload creator 函数,第一个参数是dispatch 时传入的请求参数,第二个才是包含 dispatch、getState 的 thunkAPI 对象。当前错误的参数传递会导致 MSAL 获取 token 时传入无效值,进而引发状态异常,最终触发持久化时的 reducer 错误。

修正后的 fetchUsersToken:

export const fetchUsersToken = createAsyncThunk(
  "users/fetchUsersToken",
  async (requestParams, { rejectWithValue }) => {
    try {
      const data = await msalInstance.acquireTokenSilent(requestParams);
      return data.accessToken;
    } catch (error) {
      return rejectWithValue(error.response?.data || error.message);
    }
  }
);

2. 清除旧持久化数据

如果 localStorage 中存储的旧数据结构与当前 reducer 的状态结构不兼容,也会导致 redux-persist 恢复状态时出错。可以手动清除浏览器 localStorage 中的 persist:root 条目,再测试页面刷新是否正常。

3. 确保 Redux Provider 唯一

检查应用中是否存在多个 Redux Provider 嵌套的情况(当前代码中已注释掉重复的 Provider,但需保持全局仅一个 Provider 实例),避免 Store 实例混乱引发异常。

4. 版本兼容性检查

确保 @reduxjs/toolkit 和 redux-persist 版本兼容,可尝试更新至最新稳定版:

npm update @reduxjs/toolkit redux-persist

额外优化

  • 在 fetchUsersToken.rejected 分支中添加错误状态存储,方便调试:
.addCase(fetchUsersToken.rejected, (state, action) => {
  state.loading = false;
  state.error = action.payload;
});
  • 组件内建议使用 useDispatch Hook 而非直接调用 store.dispatch,比如 LandingPage.js 中:
import { useDispatch } from 'react-redux';
import { fetchUsersToken } from '../userSlice';

// 组件内部
const dispatch = useDispatch();
const request = { ...loginRequest, account: accounts[0] };
dispatch(fetchUsersToken(request));

内容的提问来源于stack exchange,提问作者Lakshmi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 02:50:27