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

Formik自定义onChange事件无法覆盖默认行为、字符串转数值不生效排查

问题根源
  • 属性顺序导致自定义onChange被覆盖:你在自定义Input组件内部为<C.Input />绑定属性时,先指定了onChange={handleChange},随后执行了{...props}展开操作。而props中包含了Formik的field对象自带的原生onChange属性,JSX中后声明的属性会覆盖前序的同名属性,因此你传入的自定义处理函数完全没有生效,自然不会打印log。
  • 补充说明:field对象默认包含onChange/onBlur/name/value四个属性,你没有在自定义组件入参处排除原生onChange,导致它被传入props最终覆盖了你的自定义逻辑。
修复方案

方案1:调整属性绑定顺序(最简单)

把onChange的绑定移到{...props}之后,确保自定义逻辑优先级高于默认属性:

export const Input = ({mask, handleChange, ...props}: InputProps) => {
  const handleInput = useCallback(
    (e: React.FormEvent<HTMLInputElement>) => {
      if (mask === 'currency') {
        currency(e)
      }
    },
    [mask]
  )

  return (
    <C.Input
      inputMode={'numeric'}
      onInput={handleInput}
      {...props}
      {/* 放在展开后面,覆盖props自带的onChange */}
      onChange={handleChange}
    />
  )
}

方案2:显式排除原生onChange(更稳妥,避免隐式覆盖)

在组件入参处直接把Formik自带的onChange过滤掉,从根源避免冲突:

// 入参多接收一个onChange,直接丢弃不使用
export const Input = ({mask, handleChange, onChange, ...props}: InputProps) => {
  const handleInput = useCallback(
    (e: React.FormEvent<HTMLInputElement>) => {
      if (mask === 'currency') {
        currency(e)
      }
    },
    [mask]
  )

  return (
    <C.Input
      inputMode={'numeric'}
      onInput={handleInput}
      onChange={handleChange}
      {...props}
    />
  )
}
额外注意事项
  • 如果你需要保留Formik默认onChange的部分行为,可以在你自定义的handleChange中手动调用field.onChange(e),再执行数值转换逻辑。
  • 确保parseValue方法能正确处理经过currency掩码格式化后的字符串(比如去掉货币符号、千分位分隔符等),避免转换得到NaN。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 17:54:03