Redux中异步action怎么写才不会报错?

Air-艳珂 阅读 49

我最近在用Redux做登录功能,想在dispatch里发请求,但一调用就报错说“Actions must be plain objects”。我查了文档说要用中间件,但我已经装了redux-thunk,也按教程配置了,还是不行。

这是我的action代码:

export const login = (credentials) => {
  return async (dispatch) => {
    dispatch({ type: 'LOGIN_REQUEST' });
    const res = await fetch('/api/login', {
      method: 'POST',
      body: JSON.stringify(credentials)
    });
    dispatch({ type: 'LOGIN_SUCCESS', payload: res.data });
  };
};

store配置里也加了applyMiddleware(thunk),但一触发这个action就崩溃,到底哪里漏了?

我来解答 赞 8 收藏
二维码
手机扫码查看
2 条解答
Good“路阳
兄弟,你这个代码写的是对的,问题基本出在 store 创建那边。

最常见的原因是参数顺序搞错了。Redux 4.x+ 版本里 createStore 的签名是 createStore(reducer, preloadedState, enhancer),好多人写成:

const store = createStore(reducer, applyMiddleware(thunk));


这样是错的!第二个参数会被当成 preloadedState 而不是 enhancer。

正确写法:

import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers';

const store = createStore(rootReducer, applyMiddleware(thunk));


或者如果你想加初始状态:

const store = createStore(rootReducer, { /* 初始state */ }, applyMiddleware(thunk));




另外还有一种可能:你在用 Redux Toolkit 但写法还是原生那套。Redux Toolkit 的 configureStore 默认就内置了 thunk,不用再单独装:

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

const store = configureStore({
reducer: {
auth: authReducer,
},
// 这里不用加 applyMiddleware(thunk),已经内置了
});


你看看你是哪种情况?把 store 创建的代码贴出来我帮你看看具体哪里不对。
点赞
2026-03-13 06:04
郭云的笔记
啊,这种报错我见过太多次了。你的thunk写法基本是对的,但有几个细节可能漏了:

1. 确认store配置正确:
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';

const store = createStore(
rootReducer,
applyMiddleware(thunk) // 这里必须传进去
);


2. 你的action代码有个小问题,fetch返回的res.data是undefined,应该先解析json:
建议改成这样:
export const login = (credentials) => {
return async (dispatch) => {
dispatch({ type: 'LOGIN_REQUEST' });
try {
const res = await fetch('/api/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(credentials)
});
const data = await res.json(); // 加上这行
dispatch({ type: 'LOGIN_SUCCESS', payload: data });
} catch (err) {
dispatch({ type: 'LOGIN_FAILURE', error: err.message });
}
};
};


我顺手加了错误处理和headers,这样更健壮。常见问题就是漏了res.json()或者store没正确配置中间件。
点赞 3
2026-03-06 12:15