ReactJS 函数组件如何访问 state?使用 Hooks 做表单验证报 includes 错误
问题根因
- 状态无初始默认值:所有
useState调用未传入初始值,导致email、password初始状态为undefined,调用字符串方法includes、读取length属性时直接抛出类型错误。你在类组件中运行正常,大概率是类组件初始化state时给了空字符串作为默认值。 - 提交事件绑定错误:按钮处写的
onClick={Submit()}会在组件渲染时直接执行Submit函数,而非点击时触发,此时用户还未输入任何内容,email仍为undefined,直接触发报错。 - 状态更新写法错误:
setemailerror("Email not contain @") && setpasserror("Password length is less than 5")误用了逻辑与运算符,setState返回值为undefined,会导致第二个状态更新永远不会执行,需拆为两行独立语句。 - 校验函数返回不全:
valid函数的前三个判断分支没有显式返回值,默认返回undefined,会导致后续校验逻辑判断异常。
修复后完整代码
import React,{useState} from 'react'; export default function Main(){ // 给所有状态添加初始默认值 const [name, setname]= useState('') const [email, setemail]= useState('') const [password, setpassword]= useState('') const [check, setcheck]= useState(false) const [emailerror, setemailerror]= useState('') const [passerror, setpasserror]= useState('') function getdata(e){ e.preventDefault() } function valid(){ if(!email.includes("@") && password.length<5){ setemailerror("Email not contain @") setpasserror("Password length is less than 5") return false } else if (!email.includes("@")){ setemailerror("Email not contain @") return false } else if (password.length<5){ setpasserror("password length is less than 5") return false } else{ return true } } function Submit(){ setemailerror("") setpasserror("") if(valid()){ alert("Hurry!! Form submitted") } } return( <div> <form onSubmit={getdata}> <span>Full Name: </span><input name= "userName" type="text" required onChange={(e)=>setname(e.target.value)} value={name}></input><br/><br/> <span>Email: </span><input name= "Email" type="text" required onChange={(e)=>setemail(e.target.value)} value={email}></input><br /><br/> <p>{emailerror}</p> <span>Password: </span><input name= "Password" type="password" required onChange={(e)=>setpassword(e.target.value)} value={password}></input><br/><br /> <p>{passerror}</p> <span>select option: </span><select> <option>Man 1</option> <option>Man 2</option> <option>Man 3</option> <option>Man 4</option> </select><br /><br /> <span>T&c</span><input type="checkbox" onChange={(e)=>setcheck(e.target.checked)} checked={check}></input><br /><br /> {/* 修正事件绑定,传入函数引用而非直接执行 */} <button type="submit" onClick={Submit}>Submit</button> </form> </div> ) }
可选优化建议
- 可将提交逻辑统一放到form的
onSubmit事件中处理,无需同时绑定表单提交和按钮点击两个事件,避免逻辑冲突 - 校验前可增加非空判断,进一步提升代码鲁棒性
- 可对邮箱格式做更完善的正则校验,而不只是判断是否包含@符号
内容的提问来源于stack exchange,提问作者Ankit Kumar
相关产品推荐
相关产品推荐

