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

React预填充表单输入框如何添加校验?提交空值报undefined如何解决

你代码里的校验逻辑存在几个核心错误,调整后就能正常运行:

  • 混淆了undefined原始值和字符串'undefined',你所有判断里写的!== 'undefined'是对比字符串,而清空输入后拿到的是undefined类型的值,判断自然不生效
  • valid函数没有返回布尔值,导致提交时if (valid())的判断永远为假,后续提交逻辑不会执行
  • 直接修改原state中的data对象,属于可变数据更新,会导致React状态更新异常
  • 只做了非undefined判断,没处理用户输入为空字符串的场景,也没加手机号格式校验

修改后的完整代码

const EditContact = inject('Contacts')(observer((props) => {
  const { text, Contactfirst, apptContacts } = props;
  const { updateContact } = apptContacts;
  const CMS = text.appointmentManager.editAppointmentContact;
  const [state, setState] = React.useState({
    data: {
      // 初始化时给后端返回值兜底,避免初始为undefined
      firstName: Contactfirst[0] ?? '',
      lastName: Contactfirst[1] ?? '',
      number: Contactfirst[2] ?? '',
    },
    firstNameValid: '',
    lastNameValid: '',
    numberValid: '',
  });
  const handleTextareaChange = (event) => {
    const { name, value } = event.target;
    // 采用不可变方式更新状态,不直接修改原state对象
    setState(prev => ({
      ...prev,
      data: {
        ...prev.data,
        [name]: value
      }
    }));
  };
  const valid = () => {
    let isValid = true;
    const errors = {
      firstNameValid: '',
      lastNameValid: '',
      numberValid: ''
    };

    // 名字必填校验
    if (!state.data.firstName.trim()) {
      errors.firstNameValid = 'Required.Please enter your given name.';
      isValid = false;
    }
    // 姓氏必填校验
    if (!state.data.lastName.trim()) {
      errors.lastNameValid = 'Required.Please enter your family name.';
      isValid = false;
    }
    // 手机号校验,可根据实际业务调整正则规则
    const phoneReg = /^1[3-9]\d{9}$/;
    if (!state.data.number.trim()) {
      errors.numberValid = 'Required.Please enter your mobile number.';
      isValid = false;
    } else if (!phoneReg.test(state.data.number.trim())) {
      errors.numberValid = 'Please enter a valid mobile number.';
      isValid = false;
    }

    setState(prev => ({
      ...prev,
      ...errors
    }));
    return isValid;
  };
  const saveButton = () => {
    if (valid()) {
      const personName = `${state.data.firstName} ${state.data.lastName}`;
      const primaryContact = {
        name: personName,
        phoneNumber: state.data.number,
      };
      // 此处补充你的提交逻辑,比如调用updateContact接口
    }
  };
  return (
    <div>
      <VerticalSpacing size={ABLE_SPACING_SIZE.spacing4x} />
      <h1 tabIndex="-1" className="HeadingB mt-sheet-heading">
        {CMS.heading1}
      </h1>
      <VerticalSpacing size={ABLE_SPACING_SIZE.spacing3x} />
      <TextField id="givenName" name="firstName" label={CMS.name} onChange={handleTextareaChange} value={state.data.firstName} />
      <p>{state.firstNameValid}</p>
      <VerticalSpacing size={ABLE_SPACING_SIZE.spacing3x} />
      <TextField id="familyName" name="lastName" label={CMS.familyName} onChange={handleTextareaChange} value={state.data.lastName} />
      <p>{state.lastNameValid}</p>
      <VerticalSpacing size={ABLE_SPACING_SIZE.spacing3x} />
      <TextField id="mobileNumber" name="number" label={CMS.mobile} onChange={handleTextareaChange} value={state.data.number} />
      <p>{state.numberValid}</p>
      <VerticalSpacing size={ABLE_SPACING_SIZE.spacing4x} />
      <ActionButton className={styles.saveCta} variant="HighEmphasis" label={CMS.saveCTA} onClick={() => saveButton()} />
    </div>
  );
}));

export default EditContact ;

关键改动说明

  1. 初始化状态时用空值合并运算符??给后端返回值做兜底,避免初始值为undefined
  2. 输入框的change事件改为不可变方式更新状态,保证React能正常触发重渲染
  3. 重写了校验逻辑,分别对三个字段做必填校验,手机号额外增加了格式校验,校验不通过时设置对应错误提示,校验通过返回true
  4. 简化了输入框的value属性,因为初始化已经做了兜底,不需要再额外判断undefined
  5. 校验函数新增了布尔值返回,提交逻辑只有在校验全部通过后才会执行

内容的提问来源于stack exchange,提问作者Milan Sai

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 13:45:02