React+Node.js中Redux注册函数传FormData时出现Undefined问题
我用Redux实现注册功能,已经配置好store、reducer和register()函数,但调用注册API时无法完成用户注册:Redux actions文件中所有参数均显示undefined;Redux DevTools中出现Node.js后端返回的验证提示“Name is Required”“Username is Required”,说明输入的所有值都没传到API。作为Redux新手,不知道怎么调试和定位问题。
以下是我的代码:
actions/auth.js
export const register = ({ name, uniID, username, email, phoneNumber, uniIDImage, password }) => async dispatch => { console.log(name, email, phoneNumber, uniIDImage, password);// 输出全部undefined const body = JSON.stringify({ name, uniID, username, email, phoneNumber, uniIDImage, password }); const emailBody = JSON.stringify({ name, email }); try { const res = await axios.post('/register', body); dispatch({ type: REGISTER_SUCCESS, payload: res.data }); } catch (err) { dispatch({ type:REGISTER_FAIL, }); } }
reducers/auth.js
import { REGISTER_SUCCESS, REGISTER_FAIL, } from "../actions/types"; const initialState = { token: localStorage.getItem('token'), isAuthenticated: null, loading: true, user: null }; export default function (state = initialState, action) { const { type, payload } = action; switch (type) { case REGISTER_SUCCESS: localStorage.setItem('token', payload.token); return { ...state, ...payload, isAuthenticated: true, loading: false } case REGISTER_FAIL: localStorage.removeItem('token'); return { ...state, token: null, isAuthenticated: false, loading: false } default: return state; } }
Register.js
import React, {useEffect, useReducer, useState} from "react"; import { connect } from "react-redux"; import PropTypes from "prop-types"; import axios from "axios" import { register } from '../../actions/auth'; const Register = ({ register }) => { const [data, setData] = useState({ name: '', uniID: '', username: '', email: '', phoneNumber: '', password: '', }); const [uniIDImage, setUniIDImage] = useState([]); const [success, setSuccess] = useState(false); const handleChange = (e) => { setData({ ...data, [e.target.name]: e.target.value }); } const handleImage = (e) => { e.persist() setUniIDImage({ pic: e.target.files[0] }); } const onRegister = async (e) => { e.preventDefault(); const formData = new FormData(); formData.append("name", data.name); formData.append("uniID", data.uniID); formData.append("username", data.username); formData.append("email", data.email); formData.append("phoneNumber", data.phoneNumber); formData.append("uniIDImage", uniIDImage.pic); formData.append("password", data.password); register({formData}); } Register.propTypes = { register: PropTypes.func.isRequired, }; export default connect(null, {register})(Register);
问题定位与解决方案
1. 参数传递不匹配
你在Register.js的onRegister函数中调用register({formData}),传递的是一个包含formData属性的对象,但actions/auth.js中的register函数期望解构出name、uniID等字段——这直接导致所有参数都为undefined。
修改方式:直接传递formData给action,同时调整action的参数接收逻辑:
修改actions/auth.js:
// 不再解构字段,直接接收formData export const register = (formData) => async dispatch => { try { // 注意:FormData不能用JSON.stringify处理,直接传入axios.post const res = await axios.post('/register', formData, { headers: { 'Content-Type': 'multipart/form-data' // 可选,axios会自动识别FormData并设置该头 } }); dispatch({ type: REGISTER_SUCCESS, payload: res.data }); } catch (err) { dispatch({ type: REGISTER_FAIL, }); } }
修改Register.js中的onRegister:
const onRegister = async (e) => { e.preventDefault(); const formData = new FormData(); formData.append("name", data.name); formData.append("uniID", data.uniID); formData.append("username", data.username); formData.append("email", data.email); formData.append("phoneNumber", data.phoneNumber); formData.append("uniIDImage", uniIDImage.pic); formData.append("password", data.password); // 直接传递formData,而不是包在对象里 register(formData); }
2. FormData处理错误
原action中用JSON.stringify处理FormData是无效的——FormData是特殊的表单数据对象,转JSON后会变成空对象{},导致后端接收不到任何数据。必须直接将FormData作为请求体传递给axios。
3. 组件初始值小问题
Register.js中uniIDImage初始值设为[],但handleImage中设置的是对象{pic: ...},初始值改成{}更合理,避免访问uniIDImage.pic时可能出现的错误:
const [uniIDImage, setUniIDImage] = useState({});
新手调试建议
- 组件内验证:在
onRegister中先打印formData(可以用console.log([...formData])查看所有键值对),确认输入的数据已经正确存入FormData; - Action内验证:在action的
register函数开头打印formData,确认接收到的参数正确; - 浏览器Network面板:打开浏览器开发者工具的Network标签,找到
/register请求,查看Request Payload里的内容是否正确; - Redux DevTools:查看触发的action的payload,确认数据是否传入Redux流程。
内容的提问来源于stack exchange,提问作者motionless570

