如何使用react-hook-form实现密码与确认密码的校验?
React Hook Form 密码确认校验统一错误展示方案
问题描述
使用React Hook Form开发注册功能时,卡在密码与确认密码的校验环节。查阅资料大多用Yup实现校验,但希望不用Yup,且让确认密码的错误提示和其他输入框保持一致(通过error={}和helperText展示,而非Toast或console.log)。
解决方案
核心是利用React Hook Form的watch方法监听密码输入,在确认密码的register规则中添加自定义校验逻辑,将错误信息存入errors对象,从而复用现有错误展示逻辑。
修改后的完整代码:
import React from 'react' import TuaLogo from '../../assets/tua.png' import { useForm } from 'react-hook-form' const USER_REGEX = /^[A-z][A-z0-9-_]{3,23}$/; const PWD_REGEX = /^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#$%]).{8,24}$/; const ID_REGEX = /^[0-9]{10}$/; const Register = () => { // 解构watch方法,用于监听password字段实时值 const { register, handleSubmit, watch, formState: { errors } } = useForm() // 监听password输入值 const password = watch('password') const onSubmit = (data) => { // 校验已在字段注册阶段完成,无需手动判断密码一致性 console.log(data) } return ( <Container> <Box sx={{display:'flex', alignItems:'center', justifyContent:'center', width: '100%', height: '100vh'}}> <Box sx={{display:'flex', borderRadius: '20px', alignItems:'center', justifyContent: 'center', height: '900px', width: '400px', flexDirection: 'column', padding: '20px', boxShadow: 3}}> <Box sx={{display: 'flex', alignItems:'center', justifyContent:'center', padding: '20px',width: '150px' }}> <Box component="img" sx={{width: '100%', height: '100%', objectFit: 'contain'}} src={TuaLogo}></Box> </Box> <Typography my={4} sx={{ typography: {xs: 'body1', md: 'h5'}}}>E-Benta || TUA-MARKETPLACE</Typography> <form onSubmit={handleSubmit(onSubmit)} style={{width: '100%', display: 'flex', flexDirection:'column', gap: '20px'}}> <TextField variant="outlined" name="username" required label="Username" fullWidth autoComplete='username' autoFocus {...register('username', {required: "Required", pattern: {value: USER_REGEX, message: "Username should be 3-16 characters and shouldn't include any special character!" }})} error={!!errors?.username} helperText={errors?.username ?errors.username.message: null} /> <TextField variant="outlined" name="email" label="Email" required fullWidth type="email" autoComplete='email' autoFocus {...register('email', {required: "Required", pattern: { message: "It should be a valid email address!" }})} error={!!errors?.email} helperText={errors?.email ?errors.email.message: null} /> <TextField variant="outlined" name="studentid" label="Student ID" required fullWidth type="text" autoComplete='text' autoFocus {...register('studentid', {required: "Required", pattern: {value: ID_REGEX, message: "Please Enter your Student ID properly" }})} error={!!errors?.studentid} helperText={errors?.studentid ? errors.studentid.message: null} /> <TextField variant="outlined" name="password" label="Password" required fullWidth type="password" autoComplete='password' autoFocus {...register('password', {required: "Required", pattern: {value: PWD_REGEX, message: "Password should be 8-24 characters and include at least 1 letter, 1 number and 1 special character!" }})} error={!!errors?.password} helperText={errors?.password ? errors.password.message: null} /> <TextField variant="outlined" name="password1" label="Confirm Password" required fullWidth type="password" autoComplete='password' autoFocus {...register('password1', { required: "Required", // 自定义校验规则,对比watch到的password值 validate: (value) => { return value === password || "Password does not match" } })} error={!!errors?.password1} helperText={errors?.password1 ? errors.password1.message: null} /> <Button type="submit" variant="contained">Register</Button> </form> </Box> </Box> </Container> ) } export default Register
关键修改说明
- 新增
watch方法监听password字段的实时输入值,用于确认密码的校验对比 - 调整确认密码的
register规则:移除错误的pattern嵌套结构,改用validate字段实现自定义校验,校验不通过时直接返回错误信息字符串 - 删除
onSubmit中手动判断密码一致性的逻辑,因为校验已提前在字段注册阶段完成 - 移除了不再需要的
toast依赖
修改后,确认密码的错误会自动存入errors.password1,和其他输入框的错误展示逻辑完全统一,无需额外处理。
内容的提问来源于stack exchange,提问作者Stykgwar
相关产品推荐
相关产品推荐

