Я использую redux-toolkit
для получения accessToken от MSAL и redux-persist
для сохранения хранилища в localStorage. Я получаю результаты поиска на странице списка клиентов. Когда я обновляю страницу, она работает нормально. Но несколько минут назад он выдает мне ошибку «Ошибка в функции eval в ./node_modules/redux-persist/es/persistReducer.js: 144 baseReducer не является функцией». Я не мог понять, где я делаю неправильно
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;
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';
// Global styles and component-specific styles.
//For changing default blue color for mui text-fields
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 (где я отправляю действие.)
const request = {
...loginRequest,
account: accounts[0]
}
store.dispatch(fetchUsersToken(request))
Вот мой index.js (где инициирован msalInstance)
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"
//Redux
import { Provider, useDispatch } from "react-redux";
import {store} from "../store";
//Redux Ends here
export const msalInstance = new PublicClientApplication(msalConfig)
export default function Home() {
return (
<>
<Helmet>
<title>Client Engagement Lookup</title>
</Helmet>
<MsalProvider instance = {msalInstance}>
{/* <Provider store = {store}> */}
<Layout>
<PageLayout />
</Layout>
{/* </Provider> */}
</MsalProvider>
</>
)
}
После копирования/вставки кода, которым вы поделились, в работающую программу codeandbox, мне не удалось воспроизвести описанную вами ошибку, но я вижу некоторые несоответствия в коде, особенно в файле userSlice.js
.
Основное несоответствие, которое я вижу, заключается в том, что преобразователь неправильно обращается к thunkAPI
. createAsyncThunk
создатели полезной нагрузки принимают два аргумента, первый — это arg
(например, объект request
), который передается функции, а второй — объект thunkAPI
. Обновите преобразователь, чтобы правильно деструктурировать dispatch
и getState
из объекта thunkAPI
.
export const fetchUsersToken = createAsyncThunk(
"users/fetchUsersToken",
async (request, { dispatch, getState }) => { // <-- destructure thunkAPI
try {
const { accessToken } = await msalInstance.acquireTokenSilent(request);
return accessToken;
} catch (error) {
return error.response.data;
}
}
);
Второе несоответствие, которое я заметил, было в случае редуктора fetchUsersToken.fulfilled
, где между строками использовался оператор Запятая для установки состояний loading
и users
. На самом деле это не сильно влияет, поскольку каждый операнд изменяет state
независимо, но все же должен быть исправлен для удобочитаемости и обслуживания.
const usersSlice = createSlice({
name: "users",
initialState: {
users: null,
loading: true
},
extraReducers(builder) {
builder
.addCase(fetchUsersToken.pending, (state, action) => {
state.loading = true;
})
.addCase(fetchUsersToken.fulfilled, (state, action) => {
state.loading = false; // <-- own line, expression
state.users = action.payload; // <-- own line, expression
})
.addCase(fetchUsersToken.rejected, (state, action) => {
state.loading = false;
});
}
});
export default usersSlice.reducer;
@Lakshmi А, кажется, я понимаю, что сейчас происходит. Объект request
, который был передан fetchUsersToken
, был назван dispatch
в действии и передан функции acquireTokenSilent
. Я немного пересмотрел свой ответ, пожалуйста, проверьте его, чтобы увидеть, решает ли это хотя бы проблему «отклонения всегда», которую вы только что описали.
Опять отказ :(
@Lakshmi Можете ли вы отредактировать свой пост, чтобы включить этот код и файл msalInstance?
Сделанный. пожалуйста, взгляните
Большое спасибо за ваш ответ. Я решил это сейчас. Ошибка исчезла.
Я изменил эту строку вместе с вашим предложением по изменению кода const tokenforPic = await msalInstance.acquireTokenSilent({scopes: ["User.Read"], account: account[0], }); from const tokenforPic = await msalInstance.acquireTokenSilent({scopes: ["User.Read"], account: account[0], });.then((data) => data.accessToken)
@Lakshmi А, хорошо, потому что я немного растерялся, почему повторная передача объекта запроса теперь приводила к постоянному сбою вызова. Рад, что это работает для вас сейчас. Здоровья и удачи!
Привет Дрю. Спасибо за ответ. После настройки userSlice.js на основе вашего предложения fetchUsersToken всегда отклоняется. Раньше работало. Единственное, эта ошибка basereducer появляется всякий раз, когда я обновляю страницу