React Hook Form如何限制输入大于0的数字,禁止首位输入0?
解决React Hook Form输入组件禁止0值及0开头的问题
你的代码存在几个核心问题导致校验失效:
- 正则表达式写反了:
/^[^1-9]/匹配的是开头不是1-9的内容,完全和你禁止0开头、要求值≥1的需求相反; type="number"输入框中,React Hook Form会将值解析为数字类型,而正则是针对字符串的,因此pattern规则对数字值不生效;- 原生
min="1"仅在表单提交时触发校验,无法阻止用户输入0或0开头的内容。
以下是两种可行的解决方案:
方案1:基于type="number"的优化(简单直接)
利用数字类型的特性,通过validate和min属性组合实现校验,同时辅助原生浏览器拦截:
<Input {...form.register(`pallets.${index}.weight`, { required: t('errors.emptyInput'), min: { value: 1, message: t('errors.minValue', { min: 1 }) // 自定义最小值错误提示 }, validate: (value) => { // 处理输入为空、0或小于1的情况 if (value === undefined || value < 1) { return t('errors.minValue', { min: 1 }); } return true; } })} type='number' min="1" // 原生属性辅助拦截增减按钮的非法值 />
该方案会在用户输入0或小于1的数字时实时触发校验提示,同时原生min="1"会限制输入框的增减按钮无法降到1以下。
方案2:改用type="text",精准控制输入(彻底禁止0开头)
如果需要完全阻止用户输入0开头的内容(比如012这类格式),可以切换为文本输入框,通过实时过滤+正则校验实现:
<Input {...form.register(`pallets.${index}.weight`, { required: t('errors.emptyInput'), pattern: { value: /^[1-9]\d*$/, // 匹配1-9开头、后续可跟任意数字的合法格式 message: t('errors.invalidNumber') }, validate: (value) => { const num = Number(value); if (num < 1) { return t('errors.minValue', { min: 1 }); } return true; } })} type='text' onChange={(e) => { // 实时过滤:去掉开头的0,只保留数字 const filteredValue = e.target.value.replace(/^0+/, '').replace(/[^0-9]/g, ''); // 调用React Hook Form的方法更新值 form.setValue(`pallets.${index}.weight`, filteredValue); }} />
这个方案会在用户输入时自动清理0开头的内容(比如输入0会被清空,输入012会变成12),同时确保最终输入的是≥1的合法数字。
注意:如果使用自定义
Input组件,需确保它正确传递onChange、value等props给原生input元素,否则自定义过滤逻辑可能失效。
内容的提问来源于stack exchange,提问作者Mateusz Szumilo
相关产品推荐
相关产品推荐

