动作必须是普通对象。使用自定义中间件进行异步操作。终极版

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

我一直收到 redux/typescript 的调度错误。如果有人可以帮助更正我在这里的设置,那就太好了:

商店:

import {
  configureStore,
  combineReducers,
  MiddlewareArray,
} from '@reduxjs/toolkit'

import { useDispatch } from 'react-redux'

//import slice as reducer
import userReducer from './features/userSlice'
import heroReducer from './features/heroSlice'
import menuReducer from './features/menuSlice'
import utilsReducer from './features/utilsSlice'
import templatesReducer from './features/templatesSlice'

const rootReducer = combineReducers({
  //combine all reducers
  user: userReducer,
  hero: heroReducer,
  menu: menuReducer,
  utils: utilsReducer,
  templates: templatesReducer,
})


export const store = configureStore({
  reducer: rootReducer,
  middleware: new MiddlewareArray(),
})

export type AppDispatch = typeof store.dispatch
export const useAppDispatch = () => useDispatch<AppDispatch>()

发货地点:

  useEffect(() => {
    const fetchData = () => {
      // TODO
      dispatch(fetchUser()).  <--- error portion
    }
    fetchData()
  }, [])

用户切片:

import { createSlice, createSelector, createAsyncThunk } from '@reduxjs/toolkit'
import type { PayloadAction } from '@reduxjs/toolkit'

import axios from 'axios'

export const fetchUser = createAsyncThunk(
  'user/fetchUser',
  async (thunkAPI) => {
    try {
      const response = await axios.get('/api/user', {
        headers: {
          'Content-Type': 'application/json',
        },
      })
      return response.data
    } catch (error) {
      // return rejectWithValue({ error: error.message })
      return console.log(error.message)
    }
  }
)

const userSlice = createSlice({
  name: 'user',
  initialState: {
    userData: {},
    isSubscribed: false,
  },
  reducers: {
    setUserData: (state: any, action: any) => {
      state.userData = action.payload.userData
    },
    setIsSubscribed: (state: any, action: any) => {
      state.isSubscribed = action.payload.isSubscribed
    },
  },
  extraReducers: (builder) => {
    builder.addCase(fetchUser.fulfilled, (state: any, action: any) => {
      state.userData = action.payload
      state.isSubscribed = action.payload.isSubscribed
    })
  },
})

export const userData = createSelector(
  (state: any) => ({
    userData: state.userData,
    isSubscribed: state.isSubscribed,
  }),
  (state: any) => state.userData
)

export const { setUserData, setIsSubscribed } = userSlice.actions
export default userSlice.reducer

不太确定还需要什么来消除类型错误?

原错误:

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

调度时出现类型错误(fetchUser())

'Argument of type 'AsyncThunkAction<any, void, {}>' is not assignable to parameter of type 'AnyAction''

npm ls redux 显示:

您的 middleware: new MiddlewareArray() 从商店中删除所有中间件 - 虽然通常会包含一些中间件。其中有redux-thunk,允许调度thunks。

改为:

export const store = configureStore({
  reducer: rootReducer,
})

顺便说一句你也不需要combineReducers,所以你可以

export const store = configureStore({
  reducer: {
    user: userReducer,
    hero: heroReducer,
    menu: menuReducer,
    utils: utilsReducer,
    templates: templatesReducer,
  },
})

您遇到的问题是没有可用于接收 thunk 的中间件,特别是您正在调度的 fetchUserUser thunk。

new MiddlewareArray() 的调用可能 returns 一个不包含 thunk 中间件的空中间件数组。

要引入此类中间件,您可以在配置您的店铺时通过以下方式进行:

import thunk from 'redux-thunk'

...

export const store = configureStore({
  reducer: rootReducer,
  middleware: [thunk] // add the thunk middleware
})

或者,您可以使用 getDefaultMiddleware 回调,它包括来自 'redux-thunk' 的相同 thunk 中间件以及其他有用的可串行化中间件和正在开发的 immutability-check 中间件。在此处查找更多相关文档。

这就是它的样子:

...
export const store = configureStore({
  reducer: rootReducer,
  middleware: (getDefaultMiddleware) => getDefaultMiddleware() // includes the thunk middleware
})