React密码重置表单校验:延迟触发提示与拦截非法提交方案咨询
问题1:调整校验触发时机为输入完成后
该需求可直接实现,你当前的校验逻辑绑定在输入框onChange事件中,每输入一个字符就会触发校验,只需将校验逻辑迁移到onBlur(输入框失焦事件,即用户完成输入离开输入框时触发)即可:
- 保留
onChange事件仅用于更新密码、确认密码的状态值,移除原有校验逻辑 - 给两个密码输入框新增
onBlur事件绑定,将原来的校验逻辑放到对应的失焦处理函数中
问题2:拦截不符合校验规则的提交请求
该bug的原因是handleSubmit提交逻辑中仅判断了密码非空和两次密码一致,没有校验密码长度规则,只需在提交时补充全量校验,不满足规则就直接终止流程即可,建议提交前的校验和失焦校验复用同一套规则,避免逻辑不一致。
完整修改后参考代码
useEffect(() => { if (forgetSuccess) { notify("success", "Password changed successfully"); history.push("/login"); } if (forgetError) { notify("error", forgetError); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [props]); // 仅更新密码状态,不做校验 const handlePassword = (e) => { setPassword(e.target.value) }; // 密码框失焦时触发长度校验 const handlePasswordBlur = () => { const minimumPass = 8 if (password.length < minimumPass) { setError("Password should have at least 8 characters"); } else { setError('') } } // 仅更新确认密码状态,不做校验 const handleConfirmPassword = (e) => { setConfirmPassword(e.target.value); }; // 确认密码框失焦时触发一致性+长度校验 const handleConfirmPasswordBlur = () => { if (password !== confirmPassword) { setError("Both Passwords should match"); } else if (confirmPassword.length < 8) { setError("Password should have at least 8 characters"); } else { setError("") } }; const handleSubmit = (e) => { e.preventDefault() const minimumPass = 8 // 提交前全量校验,不满足直接终止流程 if (!password || password.length < minimumPass) { setError("Password should have at least 8 characters"); return } if (password !== confirmPassword) { setError("Both Passwords should match"); return } if (resetPassword) resetPassword(secret, password); }; return ( <div className={styles.root}> <div className={styles.left_side}> <Link to="/"> <div className={styles.logo_container}> <img src={logo} alt="logo" className={styles.logo} /> <picture> <source srcSet={AutopilotWhite} media="(prefers-color-scheme: dark)" /> <img alt="autopilot" src={Autopilot} /> </picture> </div> </Link> <p className={styles.forgot_text}>Reset Your Password</p> <p className={styles.forgot_message}>Set your new password and confirm it</p> <p className={styles.error_message}>{error} </p> {errorValidation && ( <Alert severity="error" style={{ width: "400px", marginBottom: "20px" }}> {errorValidation} </Alert> )} <form onSubmit={handleSubmit} className={styles.form}> {/* 新增onBlur事件绑定 */} <input type="password" placeholder="Enter Password" className={styles.email_address} value={password} onChange={handlePassword} onBlur={handlePasswordBlur} /> <br /> <br /> {/* 新增onBlur事件绑定 */} <input type="password" placeholder="Confirm Your Password" className={styles.email_address} value={confirmPassword} onChange={handleConfirmPassword} onBlur={handleConfirmPasswordBlur} /> <Button type="submit" className={`${styles.forgot_button} ${loading && styles.forgot_button_disabled}`} disabled={loading} > {loading !== true ? <span>Save Password</span> : <span>Processing...</span>} </Button> </form> </div> <div className={styles.right_side}> <Slider /> </div> </div> ); };
注:代码中统一修正了原逻辑里
confirm_password和confirmPassword变量名混用的问题,避免因变量名错误导致的校验失效。
内容的提问来源于stack exchange,提问作者John Alesi Resurreccion
相关产品推荐
相关产品推荐

