CreateAsyncThunk 错误:操作必须是普通对象。使用自定义中间件进行异步操作

Ben*_*rla 4 javascript reactjs redux redux-thunk redux-toolkit

我目前正在设置我的 RTK(Redux 工具包)并进行了一些小测试。这是我的代码:

商店/index.js

import { configureStore } from '@reduxjs/toolkit'
import { loginSliceReducer } from './views/page/login/loginSlice'

export default configureStore({
  reducer: {
    login: loginSliceReducer
  }
})

Run Code Online (Sandbox Code Playgroud)

登录Slice.js

import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'
import ApiService from '../../services/ApiService'

export const authorize = createAsyncThunk(
  'api/authorize',
  async (email, password) => {
    const response = await ApiService.post(email, password)
    return response.data
  }
)

export const loginSlice = createSlice({
  name: 'login',
  initialState: {
    loading: true,
    token: null,
    data: []
  },
  reducers: {
    updateState: (state, action) => {
      const { payload } = action
      switch (payload.type) {
        case AUTH_SUCCESS:
          state.loading = false
          state.token = payload.token
          state.data = payload.data
          break
        default:
      }
    }
  },
  extraReducers: {
    [authorize.fulfilled]: (state, action) => {
      // ... do state update here
    }
  }
})

export default loginSlice.reducer
Run Code Online (Sandbox Code Playgroud)

登录.js

import React, { useEffect } from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { authorize } from './loginSlice'

const Login = () => {
  const dispatch = useDispatch()
  useEffect(() => {
    dispatch(authorize('testuser@example.com', 'test123'))
  }, [])

  return <div>Auth Test</div>
}
Run Code Online (Sandbox Code Playgroud)

上面的代码不起作用。我不断收到此错误:

Error: Actions must be plain objects. Use custom middleware for async actions.

在这一行: > 25 | dispatch(authorize('testuser@example.com', 'test123'))

请不要介意我在useEffect上触发授权,因为这只是检查端点是否被调用以及检查请求成功后状态是否会更新的测试。:-D

Dan*_*iel 8

我遇到了同样的问题,这是因为我添加了额外的中间件。

@reduxjs/toolkit'sconfigureStore有一些默认包含的中间件,但是如果您向该middleware属性添加任何内容,它将覆盖这些默认值。

解决方案是包含默认中间件以及您定义的中间件:

import { configureStore, getDefaultMiddleware } from '@reduxjs/toolkit';

import { loginSliceReducer } from './views/page/login/loginSlice';
import { otherMiddleware } from './middlewares/some-other-module';

export default configureStore({
  reducer: {
    login: loginSliceReducer
  },
  middleware: [ // Because we define the middleware property here, we need to explictly add the defaults back in.
    ...getDefaultMiddleware(),
    otherMiddleware
  ]
})
Run Code Online (Sandbox Code Playgroud)

注意,redux-thunk使用时不需要显式包含,@reduxjs/toolkit因为它已经是默认中间件的一部分getDefaultMiddleware()

  • 这似乎不是OP问题的解决方案。我明白这对于那些不小心覆盖了默认中间件并遇到类似错误的人来说是有价值的。RTK 团队建议的方式是使用以下中间件:(getDefaultMiddleware) =&gt; getDefaultMiddleware().concat(loggerMiddleware),``https://redux-toolkit.js.org/api/getDefaultMiddleware (3认同)

Ale*_*hur 0

看起来问题是您没有向商店添加能够处理异步操作的中间件

在你的store/index.js尝试中,比如:

import { applyMiddleware } from 'redux';
import { configureStore, getDefaultMiddleware } from '@reduxjs/toolkit'
import { loginSliceReducer } from './views/page/login/loginSlice'
import thunk from 'redux-thunk';

export default configureStore({
  reducer: {
    login: loginSliceReducer
  },
  middleware: [applyMiddleware(thunk), getDefaultMiddleware()]
})
Run Code Online (Sandbox Code Playgroud)

  • RTK 默认包含 `redux-thunk`:https://redux-toolkit.js.org/usage/usage-guide#simplifying-store-setup-with-configurestore (2认同)