score:0

I faced a similar issue recently when migrating to V7. If it can help anybody.

A parent component handling the form was passing down to a wrapper the register function, the wrapper passing it down again to an input that needed debouncing on change.

I called the register formLibraryRef in case I wanted to use a different library later but overall I had to do something like:

const { onChange, ...rest } = formLibraryRef(inputName);

pass the onChange to the function that is itself passed to the native onChange event of the input:

const handleDebouncedChange: (event: React.ChangeEvent<HTMLInputElement>) => void = (
    event: ChangeEvent<HTMLInputElement>,
  ) => {
    onChange(event);
    if (preCallback) {
      preCallback();
    }
    debounceInput(event);
  };

and then pass the rest to the input:

<input
  aria-label={inputName}
  name={inputName}
  data-testid={dataTestId}
  className={`form-control ...${classNames}`}
  id={inputId}
  onChange={handleDebouncedChange}
  onFocus={onFocus}
  placeholder={I18n.t(placeholder)}
  {...rest}
/>

The register section in the docs here: https://react-hook-form.com/migrate-v6-to-v7/ gives a bit more info on how to get the onChange and shows an example for Missing ref.

score:1

For me, decoration solution worked

const fieldRegister = register("productImage", {required: true})
const origOnChange = fieldRegister.onChange
fieldRegister.onChange = (e) => {
    const res = origOnChange(e)
    const value = e.target.value
    // do something with value
    return res
}

For field declaration use

<input {...fieldRegister}/>

score:1

Was stuck with the same problem. For me the problem was that my onChange was above the react-hook-form's {...register} and moving it below the register solved the problem for me!!

score:5

In register documentation https://react-hook-form.com/api/useform/register, sample exists on Custom onChange, onBlur section :

// onChange got overwrite by register method
<input onChange={handleChange} {...register('test')} />

// register's onChange got overwrite by register method
<input {...register('test')} onChange={handleChange}/>

const firstName = register('firstName', { required: true })
<input 
  onChange={(e) => {
    firstName.onChange(e); // method from hook form register
    handleChange(e); // your method
  }}
  onBlur={firstName.onBlur}
  ref={firstName.ref} 
/>

So for your case :

const productImageRegister = register("productImage", {required: true})
<input className="form-control"
       type="file"
       {...productImageRegister }
       onChange={e => {
           productImageRegister.onChange(e);
           handleImageUpload(e);
       }} />

score:29

https://github.com/react-hook-form/react-hook-form/releases/tag/v7.16.0

V7.16.0 has introduced this new API for custom onChange.

<input
  type="text"
  {...register('test', {
    onChange: (e) => {},
    onBlur: (e) => {},
  })}
/>

score:31

You just have to move the onChange props after {...register(...)}

const productImageField = register("productImage", { required: true });

return (
    <input
        className="form-control"
        type="file"
        {...productImageField}
        onChange={(e) => {
          productImageField.onChange(e);
          handleImageUpload(e);
     }}
    />
)

(Dec 3 2021) edit: this approach is no longer correct since react-hook-form v7.16.0's changes, see @Bill's answer.


Related Query

More Query from same tag