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

React Hook Form+MUI+Yup带掩码手机号验证失效问题求助

React Hook Form 手机号掩码与验证问题解决方案

核心问题分析

你的问题主要源于三点:

  1. react-input-mask 默认会保留掩码固定符号(如+、-),导致字段始终非空,required验证失效
  2. 未传递React Hook Form的ref给输入组件,导致表单无法正确跟踪字段状态、触发验证
  3. Yup验证逻辑未结合掩码的实际输入场景做适配

分步解决方案

1. 调整react-input-mask配置,清空无效空值

添加maskChar=""和alwaysShowMask={false},确保用户未输入数字时,字段值为空字符串:

<InputMask
  mask="+99-999-9999999"
  value={value || ""}
  onChange={onChange}
  maskChar="" // 移除占位符
  alwaysShowMask={false} // 未输入时不显示掩码框架
>

2. 修正Yup验证规则

先验证必填,再通过正则确保格式正确,最后验证长度:

const Schema = Yup.object().shape({
  cellPhone: Yup.string()
    .required('Cell phone is required')
    .matches(/^\+\d{2}-\d{3}-\d{7}$/, 'Invalid format: use +XX-XXX-XXXXXXX')
    .test(
      'exact-length',
      'Cell phone must be 15 characters total',
      (val) => val?.length === 15
    ),
});

3. 完善Controller组件的属性传递

将React Hook Form的ref传递给TextField,确保表单能正确触发验证:

<Controller
  name="cellPhone"
  control={methods.control}
  defaultValue=""
  render={({ field: { onChange, value, ref }, fieldState: { error } }) => (
    <InputMask
      mask="+99-999-9999999"
      value={value || ""}
      onChange={(e) => onChange(e.target.value)}
      maskChar=""
      alwaysShowMask={false}
    >
      {(inputProps) => (
        <TextField
          {...inputProps}
          inputRef={ref} // 传递RHF的ref给输入框
          error={!!error}
          helperText={error?.message}
          label="Cell phone"
          variant="outlined"
          type="text"
          fullWidth
          required
        />
      )}
    </InputMask>
  )}
/>

4. 确保提交逻辑正确

使用methods.handleSubmit包裹提交回调,触发完整表单验证:

const onSubmit = (data) => {
  console.log('Submitted data:', data);
};

// 提交按钮
<Button variant="contained" onClick={methods.handleSubmit(onSubmit)}>
  Submit
</Button>

内容的提问来源于stack exchange,提问作者Umar Munir

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 23:55:18