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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 19:23:27