19

I am building webapp using React and react-hook-form library. I would like to create form where change of some field triggers some event. So I need pass custom onChange

However, since v7.0 I can't use onChange because register uses its own onChange.

import React from 'react'
import { useForm } from 'react-hook-form'

const MyForm = () => {

  const form = useForm()
  const onChangeFirst = value => console.log('First:', value)
  const onChangeSecond = value => console.log('Second:', value)

  return (
    <form onSubmit={form.handleSubmit(vals => null)}>
      <input {...register('first')} />
      <input {...register('second')} />
    </form> 
  )

}

How can I pass onChangeFirst to first input and onChangeSecond to second input?

3 Answers 3

27

There are two ways to trigger onChange while input change.

1/ With Controller component (recommend)

const onChangeFirst = value => console.log('First:', value)

<Controller
  control={control}
  name="first"
  render={({field}) => (
    <input {...field} onChange={e => {
      onChangeFirst(field.value);
      field.onChange(e);
    }} />
  )}
/>

2/ With useWatch hook

 const second = useWatch({
    control,
    name: 'second'
 });

 useEffect(() => {
   console.log('Second:', second)
 }, [second])
Sign up to request clarification or add additional context in comments.

Comments

2

With watch:

const { register, watch } = useForm()
const first = watch("first")

useEffect(() => {
    // do something with first
}, [first])

…

<input {...register('first')} />

Comments

1

This works as per the documentation:

import React from "react";
import {useForm} from "react-hook-form";

const MyForm = () => {
    const form = useForm();

    return <form onSubmit={form.handleSubmit(values => console.log(values))}>
        <input {...form.register('first', {onChange: e => console.log(e.target.value)})}/>
        <input {...form.register('second', {onChange: e => console.log(e.target.value)})}/>
    </form>
}

Before I saw that the above was possible, I posted this solution which works without using a Controller component (I left it here because it contains information that might be useful to someone):

import React, {forwardRef} from "react";
import {FormProvider, useForm, useFormContext} from "react-hook-form";

const Input = forwardRef({itemKey, handleChange, ...rest}), ref => {
    const {register} = useFormContext();
    const reg = register(itemKey);
    const handleChangeWrapped = e => {
        reg.onChange(e);
        handleChange?.(e.target.value);
    }

    return <input ref={ref} {...rest} {...reg} onChange={handleChangeWrapped}/>
});

const MyForm = () => {
    const form = useForm();

    return <FormProvider {...form}>
        <form onSubmit={form.handleSubmit(values => console.log(values))}>
            <Input itemKey={'first'} handleChange={value => console.log(value)}/>
            <Input itemKey={'second'} handleChange={value => console.log(value)}/>
        </form>
    </FormProvider>
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.