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

如何在react-hook-form中实现仅允许输入数字的输入框功能

问题根因

你封装的HTextField组件中,Controller返回的onChange、value属性优先级高于外部传入的同名属性,直接覆盖了你写的数字过滤逻辑,同时你额外维护的numberInput状态和react-hook-form托管的表单状态完全脱节,所以过滤逻辑不生效。

实现方案

方案1:修改公共HTextField组件,增加通用输入预处理能力(推荐)

这种方案可复用性最高,后续其他需要输入过滤的场景都可以直接使用:

export interface HTextFieldProps extends TextFieldProps {
  control: Control<any>
  name: string
  defaultValue?: string
  // 新增输入转换回调,返回处理后的值传给表单
  transformInput?: (value: string) => string
}

export const HTextField = function HookformTextField(props: HTextFieldProps) {
  const { name, control, defaultValue = "", transformInput, ...restProps } = props

  return (
    <Controller
      control={control}
      name={name}
      render={({ field: { onChange, value }, fieldState: { error } }) => (
        <TextField
          {...restProps}
          onChangeText={(val) => {
            // 先执行自定义转换逻辑,再更新表单值
            const processedVal = transformInput ? transformInput(val) : val
            onChange(processedVal)
          }}
          value={value}
          defaultValue={defaultValue}
          error={(error && error.message) as TxKeyPath}
        />
      )}
      defaultValue={defaultValue}
    />
  )
}

调用组件时直接传入数字过滤逻辑即可,不需要额外维护本地状态:

<HTextField
  name="times"
  control={control}
  autoCapitalize="none"
  keyboardType={Platform.OS === "android" ? "numeric" : "number-pad"}
  returnKeyType="done"
  inputStyle={INPUT_STYLE}
  required
  // 传入数字过滤逻辑
  transformInput={(value) => value.replace(/[^0-9]/g, "")}
/>

方案2:增加提交校验兜底

如果需要避免极端情况出现非数字值,可以在useForm的对应字段规则中增加正则校验,提交时拦截非法值:

const { control, handleSubmit } = useForm({
  defaultValues: {
    times: ""
  },
  rules: {
    times: {
      pattern: {
        value: /^[0-9]*$/,
        message: "只能输入数字"
      }
    }
  }
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 11:48:01