我目前正在设置我的 RTK(Redux 工具包)并做了一些小测试。这是我的代码:
商店/index.js
import { configureStore } from '@reduxjs/toolkit'
import { loginSliceReducer } from './views/page/login/loginSlice'
export default configureStore({
reducer: {
login: loginSliceReducer
}
})
loginSlice.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
登录.js
import React, { useEffect } from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { authorize } from './loginSlice'
const Login = () => {
const dispatch = useDispatch()
useEffect(() => {
dispatch(authorize('[email protected]', 'test123'))
}, [])
return <div>Auth Test</div>
}
上面的代码不起作用。我不断收到此错误:
Error: Actions must be plain objects. Use custom middleware for async actions.
在这一行:
> 25 | dispatch(authorize('[email protected]', 'test123'))
请不要介意我在 useEffect 上触发授权,因为这只是一个测试,用于检查端点是否正在被调用以及检查请求成功后状态是否会更新。 :-D
我也遇到了同样的问题,这是由于我添加了额外的中间件而引起的。
@reduxjs/toolkit
的 configureStore
有一些默认包含的中间件,但是如果您向 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
]
})
注意,使用
redux-thunk
时无需显式包含 @reduxjs/toolkit
,因为它已经是 getDefaultMiddleware()
中默认中间件的一部分
看起来问题是您没有向商店添加能够处理异步操作的中间件
在你的
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()]
})
如果有多个参数要传递给动作创建者,则必须将它们传递到一个对象内。 例如,如果我必须发送电子邮件和密码作为有效负载,我将必须将它们发送到如下所示的对象中:
dispatch(authorize({email, password}))
解决此问题的一种方法是使用商店的调度方法。 这样,由于 thunk 默认包含在 Redux Toolkit (RTK) 中,您将可以访问它 - 这应该可以修复您遇到的错误。
试试这个:
商店/index.js
import { configureStore } from '@reduxjs/toolkit'
import { loginSliceReducer } from './views/page/login/loginSlice'
export default const store = configureStore({
reducer: {
login: loginSliceReducer
}
})
const useAppDispatch = () => store.dispatch
export { useAppDispatch }
登录.js
import React, { useEffect } from 'react'
import { useSelector} from 'react-redux'
import { authorize } from './loginSlice'
import { useAppDispatch } from './store/index'
const Login = () => {
const dispatch = useAppDispatch()
useEffect(() => {
dispatch(authorize('[email protected]', 'test123'))
}, [])
return <div>Auth Test</div>
}
import { configureStore } from '@reduxjs/toolkit'
import logger from 'redux-logger'
import rootReducer from './reducer'
const store = configureStore({
reducer: rootReducer,
middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(logger),
})
以上解决方案来自官方redux工具包文档: