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

React Native中React Hook Form Controller无法输入小数的问题求助

React Native + react-hook-form + Zod 小数输入问题解决

核心问题分析

  1. 小数点被自动删除:Zod定义的是number类型,输入"."时react-hook-form会将其转为NaN,触发校验失败导致值被重置。
  2. 表单提交失败:调整后输入的是字符串,但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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 03:35:10