如何在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
相关产品推荐
相关产品推荐

