ReactJS 邮箱表单验证问题:邮箱有效时无法跳转到下一页
问题根因
- 核心问题是
<form>标签内的type="submit"按钮触发了浏览器原生表单默认提交行为,会直接刷新当前页面,导致跳转逻辑未执行就被中断 - 次要可能原因是组件未被React Router注入
history对象,调用this.props.history.push时报错,跳转逻辑失效
修复步骤
1. 阻止表单默认提交行为
二选一即可:
方案A:修改按钮类型
将提交按钮的type从submit改为普通button,不会触发默认表单提交:
<button type="button" className="btn btn-success" onClick={()=>this.onSubmit()}>Login</button>
方案B:主动阻止默认事件
在提交逻辑中接收事件对象,调用preventDefault取消默认提交:
// 按钮传递事件对象 <button type="submit" className="btn btn-success" onClick={(e)=>this.onSubmit(e)}>Login</button> // 改造onSubmit方法 onSubmit(e){ e.preventDefault(); if(this.emailValidation()){ console.log(this.state); this.props.history.push('/home'); } }
2. 校验history对象是否正常注入
打开浏览器开发者工具控制台,验证邮箱通过后如果出现Cannot read property 'push' of undefined报错,说明组件没有拿到history属性,需要用withRouter高阶组件包裹导出:
// 头部引入 import { withRouter } from 'react-router-dom'; // 底部导出写法 export default withRouter(Test);
3. 可选优化项
- 将提交逻辑绑定到
form的onSubmit属性上,而非按钮的onClick,更符合前端表单操作规范 - JSX中
label标签的for属性需改为htmlFor,避免控制台语法警告
完整修复后参考代码
import React from 'react'; import { Link, withRouter } from 'react-router-dom'; import { BsBugFill, BsTools, BsColumns } from 'react-icons/bs'; const emailState = { email: '', error: '' } class Test extends React.Component { constructor(){ super(); this.state = emailState; this.onChange = this.onChange.bind(this); this.onSubmit = this.onSubmit.bind(this); } onChange(e) { this.setState({ email : e.target.value, error: '' }); } emailValidation(){ const regex = /^(([^<>()[\]\.,;:\s@\"]+(\.[^<>()[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i; if(!this.state.email || regex.test(this.state.email) === false){ this.setState({ error: "Email is not valid" }); return false; } return true; } onSubmit(e){ e.preventDefault(); if(this.emailValidation()){ console.log(this.state); this.props.history.push('/home'); } } render(){ return ( <div className="login-cot bg-danger" id="layoutAuthentication"> <div id="layoutAuthentication_content"> <main> <div className="container "> <div className="row justify-content-center "> <div className="col-lg-5 "> <div className="card shadow-lg border-0 rounded-lg mt-5 bg-secondary"> <center><h1 className="bg-warning" style={{padding:"10px",}}><b><BsBugFill /><BsTools /> <BsColumns /> BFP</b></h1></center> <div className="card-header"><h3 className="text-center my-1"><b>Login</b></h3></div> <div className="card-body"> <form onSubmit={this.onSubmit}> <div className="form-floating mb-3"> <input className="form-control" id="email" type="email" placeholder="name@example.com" value={this.state.email} onChange={this.onChange} /> <label htmlFor="email">Email address</label> <span className="text-danger">{this.state.error}</span> </div> <button type ="submit" className="btn btn-success">Login</button> </form> </div> <div className="card-footer text-center py-3"> <div className="small"><Link className="text-light" to="/signup">Need an account? Sign up!</Link></div> </div> </div> </div> </div> </div> </main> </div> </div> ) } } export default withRouter(Test);
内容的提问来源于stack exchange,提问作者Shanky Boi
相关产品推荐
相关产品推荐

