Basereducer не является функцией — Redux Toolkit с createasyncthunk

Я использую 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>
 </>
 )

}

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
0
64
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

После копирования/вставки кода, которым вы поделились, в работающую программу 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;

Привет Дрю. Спасибо за ответ. После настройки userSlice.js на основе вашего предложения fetchUsersToken всегда отклоняется. Раньше работало. Единственное, эта ошибка basereducer появляется всякий раз, когда я обновляю страницу

Lakshmi 14.02.2023 14:06

@Lakshmi А, кажется, я понимаю, что сейчас происходит. Объект request, который был передан fetchUsersToken, был назван dispatch в действии и передан функции acquireTokenSilent. Я немного пересмотрел свой ответ, пожалуйста, проверьте его, чтобы увидеть, решает ли это хотя бы проблему «отклонения всегда», которую вы только что описали.

Drew Reese 14.02.2023 17:30

Опять отказ :(

Lakshmi 14.02.2023 17:49

@Lakshmi Можете ли вы отредактировать свой пост, чтобы включить этот код и файл msalInstance?

Drew Reese 14.02.2023 18:08

Сделанный. пожалуйста, взгляните

Lakshmi 14.02.2023 18:11

Большое спасибо за ваш ответ. Я решил это сейчас. Ошибка исчезла.

Lakshmi 14.02.2023 18:39

Я изменил эту строку вместе с вашим предложением по изменению кода 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 14.02.2023 18:39

@Lakshmi А, хорошо, потому что я немного растерялся, почему повторная передача объекта запроса теперь приводила к постоянному сбою вызова. Рад, что это работает для вас сейчас. Здоровья и удачи!

Drew Reese 14.02.2023 18:40

Другие вопросы по теме