Redux异步调用API报“Actions may not have an undefined "type" property”如何解决
错误根因排查&修复方案
你遇到的Actions may not have an undefined "type" property.报错,核心原因是Redux接收到了没有type字段的非法action,具体问题和修复如下:
问题1:action创建函数导出+命名不匹配
你的actions.js中定义的setloginState没有对外导出,且和app.js中导入的login、注释中调用的setLoginState命名完全不匹配,就算走到dispatch逻辑也会触发未定义错误。
修正后的actions.js
import * as t from '../constants/actionTypes'; import axios from 'axios'; // 统一命名,加导出 export const setLoginState = (logindata) => { return { type: t.SET_LOGIN_STATE, payload: logindata, } } // 登录异步thunk单独封装,避免组件逻辑混乱 export const login = (loginFormData) => { return (dispatch) => { axios.post('/invoice/webapps/api/login', loginFormData, { headers: { Accept: 'application/json', 'Content-Type': 'application/json' }}) .then(function (response) { const responsedata = response.data if(responsedata.login_status === "Done"){ // 登录成功后dispatch同步action更新状态 dispatch(setLoginState(responsedata)) }else{ // 登录失败逻辑自行补充 console.log("登录失败") } }) .catch(function (error) { console.log(error); }); } }
问题2:useDispatch用法错误
useDispatch是钩子函数,需要先调用获取dispatch实例,不能直接把回调函数作为参数传入useDispatch,你之前的写法会导致thunk函数直接被当作action提交,没有经过thunk中间件处理,直接触发type不存在的报错。
修正后的app.js
import logo from './logo.svg'; import './App.css'; import {useForm} from 'react-hook-form'; import {useDispatch} from 'react-redux'; // 导入封装好的login异步thunk import {login} from './actions/actions'; function App() { const { register, formState: { errors }, handleSubmit } = useForm(); // 正确调用useDispatch拿到dispatch实例 const dispatch = useDispatch() const _doLogin = data => { // 手动dispatch异步thunk dispatch(login(data)) } return ( <div className="App"> <div>Login <form className="form" onSubmit={handleSubmit(_doLogin)}> 输入用户名: <input className="form-control h-auto form-control-solid py-4 px-8" type="text" placeholder="邮箱" autoComplete="off" {...register("email", { required: true, pattern: { value: /^(([^<>()[\]\.,;:\s@\"]+(\.[^<>()[\]\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/, message: '请输入合法邮箱地址', }, })}/> 输入密码: <input className="form-control h-auto form-control-solid py-4 px-8" type="password" placeholder="密码" autoComplete="off" {...register("password", { required: true, })} /> <input type="submit" value="登录"/> </form> </div> </div> ); } export default App;
其他冗余问题修复
- 你之前的
_doLogin加了多余的async关键字,内部没有使用await逻辑直接移除即可 - 你之前对response做
JSON.parse(JSON.stringify(response))是冗余操作,直接取response.data即可拿到接口返回数据 - reducer、store、actionTypes的代码逻辑没有问题,可以正常使用
内容的提问来源于stack exchange,提问作者wontone_boys
相关产品推荐
相关产品推荐

