React Native中React Hook Form Controller无法输入小数的问题求助
React Native + react-hook-form + Zod 小数输入问题解决
核心问题分析
- 小数点被自动删除:Zod定义的是
number类型,输入"."时react-hook-form会将其转为NaN,触发校验失败导致值被重置。 - 表单提交失败:调整后输入的是字符串,但Zod期望数字类型,校验不通过。
解决方案
1. 修改Zod校验规则,兼容字符串输入并转换为数字
允许字符串输入,通过transform转为数字,同时过滤无效值:
sellingPrice: z .union([z.string(), z.number()]) .refine(val => val !== '' && val !== '.', 'Selling Price is required') .transform(val => { const num = typeof val === 'string' ? parseFloat(val) : val; return isNaN(num) ? undefined : parseFloat(num.toFixed(2)); }) .refine(val => val > 0, 'Selling Price must be positive')
2. 调整Input组件逻辑,保证输入合法性
修改Controller的render逻辑,正确处理值的显示与传递:
<Controller control={control} name="sellingPrice" render={({ field: { onChange, onBlur, value } }) => ( <Input label="Selling Price" placeholder="Enter Selling Price" value={typeof value === 'number' ? value.toString() : value || ''} onBlur={onBlur} disabled={isSubmitting} onChangeText={text => { const sanitizedText = text.replace(/[^0-9.]/g, ''); if (/^\d*\.?\d{0,2}$/.test(sanitizedText)) { onChange(sanitizedText); } }} keyboardType={Platform.OS === 'ios' ? 'decimal-pad' : 'numeric'} /> )} />
关键说明
- 输入"."时会触发必填校验,但后续输入数字会自动通过。
- 最终提交的是保留两位小数的正数字,符合业务需求。
- 兼容用户输入过程中的中间状态(如单独的小数点),同时保证最终值合法。
内容的提问来源于stack exchange,提问作者Tony Ngomana
相关产品推荐
相关产品推荐

