React注册表单无法获取邮箱,console无输出,无法对接nodemailer
问题排查与修复方案
核心问题梳理
你的代码存在多处逻辑冲突和语法错误,导致无法正确获取邮箱值、传递数据到后端,以下是具体问题和修复方法:
1. 状态管理冲突:邮箱字段绑定双状态
你给邮箱输入框同时绑定了独立的email状态和values对象里的email属性,导致数据分散,且handleInput方法给values赋值时错误使用数组格式:
// 错误写法:把值包装成数组 setValues(prev => ({ ...prev, [event.target.name]: [event.target.value] }))
修复:
统一用values管理所有表单状态,删除独立的email状态,修改绑定逻辑:
// 移除独立的email状态 // const [email, setEmail] = useState(""); // 修改handleInput,赋值字符串而非数组 const handleInput = (event) => { setValues(prev => ({ ...prev, [event.target.name]: event.target.value })) } // 邮箱输入框改为绑定values里的email <input type="email" placeholder="Email" name='email' value={values.email} onChange={handleInput} />
2. 提交逻辑冲突:按钮点击与表单提交重复绑定
提交按钮同时绑定onClick={sendEmail}和表单onSubmit={handleSubmit},两个函数都调用e.preventDefault(),导致逻辑混乱,sendEmail的控制台输出被阻断。
修复:
将发送邮件逻辑整合到handleSubmit中,移除按钮的onClick事件:
const handleSubmit = async (event) => { event.preventDefault(); const validationErrors = Validation(values); setErrors(validationErrors); if (!validationErrors.name && !validationErrors.email && !validationErrors.password) { try { // 提交注册数据 await axios.post('http://localhost:8081/signup', values); // 发送邮件请求 const emailRes = await fetch('http://localhost:8081/signup', { method: "POST", headers: { // 注意是headers不是header "Content-Type": "application/json" }, body: JSON.stringify({ email: values.email }) }); console.log(emailRes); navigate('/'); } catch(err) { console.error('请求失败:', err); } } }
同时修改按钮:
<button type='submit' className="submit-button">Sign Up</button>
3. 异步状态更新导致判断错误
setErrors是异步操作,调用后立即判断errors会拿到旧值,永远无法触发提交逻辑。
修复:
直接用Validation返回的结果判断,不依赖errors状态:
const validationErrors = Validation(values); setErrors(validationErrors); if (!validationErrors.name && !validationErrors.email && !validationErrors.password) { // 提交逻辑 }
4. Fetch请求头拼写错误
sendEmail里的请求头写成header,正确应为headers,导致后端无法解析JSON数据:
// 错误 header: { "Content-Type": "application/json" } // 正确 headers: { "Content-Type": "application/json" }
5. 缺失密码输入框
values状态包含password但表单无对应输入框,导致Validation因password为空报错,无法触发提交。
修复:
添加密码输入框并绑定values状态:
<div className="input"> <img src={/* 密码图标路径 */} alt="" style={{ width: '20px', height: '20px' }} /> <input type="password" placeholder="Password" name='password' value={values.password} onChange={handleInput} /> {errors.password && <span className='text-danger'>{errors.password}</span>} </div>
修复后的完整代码示例
import React, { useState } from 'react' import './LoginSignUp.css' import email_icon from '../Assets/email_icon.png' import person_icon from '../Assets/person_icon.png' import password_icon from '../Assets/password_icon.png' // 假设你有密码图标 import { Link, useNavigate } from 'react-router-dom' import Validation from './SignUpValidation'; import axios from 'axios' export const SignUp = () => { const [values, setValues] = useState({ name: '', email: '', password: '' }) const navigate = useNavigate(); const [errors, setErrors] = useState({}) const handleInput = (event) => { setValues(prev => ({ ...prev, [event.target.name]: event.target.value })) } const handleSubmit = async (event) => { event.preventDefault(); const validationErrors = Validation(values); setErrors(validationErrors); if (!validationErrors.name && !validationErrors.email && !validationErrors.password) { try { // 提交注册数据到后端 await axios.post('http://localhost:8081/signup', values); // 发送邮件请求 const emailRes = await fetch('http://localhost:8081/signup', { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ email: values.email }) }); console.log(emailRes); navigate('/'); } catch(err) { console.error('请求失败:', err); } } } return ( <div className='container'> <div className="header"> <div className="text">Sign Up</div> <div className="underline"></div> </div> <form className="inputs" onSubmit={handleSubmit}> <div className="row"> <div className="input"> <img src={person_icon} alt="用户名图标" style={{ width: '20px', height: '20px' }} /> <input type="text" placeholder="Name" name='name' value={values.name} onChange={handleInput} /> {errors.name && <span className='text-danger'>{errors.name}</span>} </div> <div className="input"> <img src={email_icon} alt="邮箱图标" style={{ width: '20px', height: '20px' }} /> <input type="email" placeholder="Email" name='email' value={values.email} onChange={handleInput} /> {errors.email && <span className='text-danger'>{errors.email}</span>} </div> </div> <div className="input"> <img src={password_icon} alt="密码图标" style={{ width: '20px', height: '20px' }} /> <input type="password" placeholder="Password" name='password' value={values.password} onChange={handleInput} /> {errors.password && <span className='text-danger'>{errors.password}</span>} </div> <div className="submit-container"> <button type='submit' className="submit-button">Sign Up</button> <Link to="/" className="submit-button">Login</Link> </div> </form> </div> ) }
内容的提问来源于stack exchange,提问作者Shreyansh
相关产品推荐
相关产品推荐

