React组件onChange事件无法打印值的技术问题求助
解决React Hook Form结合react-input-mask时onChange回调不触发的问题
问题背景
使用react-hook-form的Controller封装react-input-mask组件时,传入的自定义onChange回调无法触发,父组件中无法打印输入值。
原因分析
你在InputMask组件上先声明了onChange={onChange},随后展开了{...field}。而Controller提供的field对象自带onChange方法(用于同步表单状态),后展开的属性会覆盖之前的声明,导致自定义的onChange被忽略。
解决方案
有两种可行的修改方式:
方式一:调整属性顺序,优先保留自定义onChange
先展开{...field},再单独设置自定义的onChange,这样自定义回调不会被覆盖,同时也能保留field中的其他属性(如value、name等)。
修改后的TimerInput组件关键代码:
{showCurrencyMask ? ( <InputMask className={styles.inputMask} type={type} name={name} step={step} placeholder={placeholder} mask="9.99 €" maskChar="0" alwaysShowMask {...field} // 先展开field的基础属性 onChange={onChange} // 再设置自定义onChange,覆盖field自带的onChange /> ) : ( <InputMask className={styles.inputMask} type={type} name={name} step={step} placeholder={placeholder} {...field} onChange={onChange} /> )}
方式二:在自定义onChange中调用field的onChange
如果需要同时触发表单状态更新和自定义回调,可以封装一个新的处理函数,在其中同时执行自定义逻辑和field.onChange,保证表单值同步。
修改TimerInput组件:
render={({ field }) => { const handleInputChange = (e) => { // 先执行父组件传入的自定义回调 if (onChange) { onChange(e); } // 再执行react-hook-form的field.onChange,同步表单状态 field.onChange(e); }; return ( <div className={styles.inputBox} style={style}> <label className={styles.title}>{label}</label> <div className={styles.inputMaskDiv}> <img className={styles.inputImg} src={src} /> {showCurrencyMask ? ( <InputMask className={styles.inputMask} type={type} name={name} step={step} placeholder={placeholder} mask="9.99 €" maskChar="0" alwaysShowMask {...field} onChange={handleInputChange} // 使用封装后的处理函数 /> ) : ( <InputMask className={styles.inputMask} type={type} name={name} step={step} placeholder={placeholder} {...field} onChange={handleInputChange} /> )} </div> </div> ); }}
验证回调有效性
父组件的handlePercentage可以正常打印输入值:
const handlePercentage = (e) => { console.log(e.target.value); };
注意:方式二更稳妥,因为它同时保证了表单状态的更新和自定义逻辑的执行,避免因覆盖field.onChange导致表单值不同步的问题。
内容的提问来源于stack exchange,提问作者Somesh Bhandari
相关产品推荐
相关产品推荐

