You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React函数组件使用useState做表单验证提交后错误不渲染如何解决

根因分析

React的状态更新依赖引用变化做浅比较判断是否重渲染。你在handleSubmit中直接通过let errors = validation获取了原有状态对象的引用,后续修改errors的属性属于原地修改状态,对象本身的引用没有变化,React会认为validation状态没有发生改变,因此不会触发组件重渲染。只有当你在输入框输入内容触发inputValues状态更新时,组件才会重渲染,顺带显示最新的错误信息。

修复方案

按以下步骤修改即可解决问题,同时还附带你代码里其他隐性bug的修复:

  1. 替换错误对象的初始化逻辑,创建全新的对象而不是复用原有状态的引用
    把handleSubmit里的let errors = validation改成:
    let errors = { ...validation };
    // 或者直接初始化为空对象,因为你后续会给所有字段赋值:
    // let errors = {};
    
  2. 修复正则表达式错误:你当前把正则用引号包成了普通字符串,match方法无法正常校验规则,需要去掉引号改为正则字面量,同时注意特殊字符转义:
    // 邮箱正则去掉引号,点号加转义
    const emailCond = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/;
    // 密码校验的三个正则同样去掉引号
    const cond1 = /^(?=.*[a-z]).{6,20}$/;
    const cond2 = /^(?=.*[A-Z]).{6,20}$/;
    const cond3 = /^(?=.*[0-9]).{6,20}$/;
    
  3. 修复确认密码校验的逻辑错误:
    • 把inputValues.Password改为inputValues.password(状态字段是小写p,你写了大写P导致比对永远失败)
    • 确认密码校验通过时,不要清空密码字段的错误,改为清空确认密码自己的错误:
    if (!inputValues.confirmPassword) {
      errors.confirmPassword = 'Password confirmation is required';
    } else if (inputValues.confirmPassword !== inputValues.password) {
      errors.confirmPassword = 'Password does not match confirmation password';
    } else {
      errors.confirmPassword = ''; // 原来这里写错成errors.password = ''
    }
    
  4. 可选优化:把邮箱的错误提示{validation.email && <p>{validation.email}</p>}移到邮箱输入框的form-control div内部,和其他字段的结构保持一致,避免样式错位。

内容的提问来源于stack exchange,提问作者Agustin Polegre

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 12:36:04