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

