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

如何在React Hook Form手机号输入框中禁止输入“e”和“-”字符?

问题根因

原生设置type="number"的输入框,浏览器本身就会放开科学计数法相关的输入许可——也就是字符e、正负号+/-、小数点.,这些是浏览器层面的内置行为,不是控件的bug。

你当前的拦截逻辑完全失效,核心问题有两个:

  • 正则判断逻辑错位:/[^e]/.test(e.target.value) 的判断规则是“输入值中存在任意非e的字符就返回true”,只要你输入的内容不是纯e,不管里面夹杂多少e、-都会触发onChange,根本起不到拦截作用
  • 拦截范围过窄:正则只排除了e,完全没覆盖-、小数点等其他非法字符,再加上没做空值兜底,很容易出现输入卡滞、值不同步的运行异常。
可落地的解决方案

方案1(最优推荐)

做手机号输入不需要强依赖type="number"属性,替换成文本类型+数字键盘属性,从根源规避非法字符输入入口:

  • 把输入框的type从number改成text
  • 增加inputMode="numeric"属性,手机端会直接唤起纯数字键盘,没有e、-等字符的输入入口
  • 在onChange逻辑里统一做字符过滤,仅保留0-9的数字

完整可运行代码如下:

<Controller
  name="phone"
  control={control}
  rules={{ 
    required: '请输入手机号',
    pattern: /^1[3-9]\d{9}$/,
  }}
  render={({ onChange, value, ref }) => (
    <Input
      ref={ref}
      type="text"
      inputMode="numeric"
      label="手机号"
      maxLength={11}
      onChange={(e) => {
        // 正则替换掉所有非数字字符,过滤所有非法输入
        const filteredValue = e.target.value.replace(/\D/g, '')
        onChange(filteredValue)
      }}
      val={value ?? ''}
    />
  )}
/>

方案2(必须保留number类型时的适配方案)

如果业务场景要求必须保留type="number"属性,需要做三层适配,解决运行异常问题:

  • 替换原有的错误onChange判断逻辑,用字符替换的方式过滤所有非数字内容,不要用test判断做分支拦截
  • 增加onKeyDown事件,从键盘输入层直接阻断e、-等非法字符的输入
  • 给输入框的展示值加空值兜底,避免number类型控件把空值默认显示为0

核心适配代码片段:

<Input
  ref={ref}
  type="number"
  label="手机号"
  onChange={(e) => {
    // 过滤掉e、-、+、.等所有非数字字符
    const filteredValue = e.target.value.replace(/[^\d]/g, '')
    onChange(filteredValue)
  }}
  onKeyDown={(e) => {
    // 拦截非法字符的键盘输入
    const forbiddenKeys = ['e', 'E', '-', '+', '.']
    if (forbiddenKeys.includes(e.key)) {
      e.preventDefault()
    }
  }}
  // 空值兜底,避免显示默认0
  val={value ?? ''}
/>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.26 11:27:07