'Custom onChange for React Hook Form and watch()
I am trying to write a custom onChange
and watch
the change.
Error:
The watched myValue
does not register the changes in the dropdown. Any ideas why?
According to the API documentation, this is possible by doing the following:
export default function App() {
const { register, watch } = useForm();
const fruits = register("fruits");
const myValue = watch("fruits", "default");
return (
<div className="App">
<h1>{myValue}</h1>
<select
onChange={(e) => {
fruits.onChange(e); // react hook form onChange
console.log("Here would go the my onChange"); // my onChange
}}
onBlur={fruits.onBlur}
ref={fruits.ref}
>
<option value="1Banana">Banana</option>
<option value="1Kiwi">Kiwi</option>
<option value="1Mango">Mango</option>
</select>
</div>
);
}
You may find the upper example here:
Solution 1:[1]
You are not passing the name
prop to your select
. The documentation is saying you should be doing this by default:
<select {...register('fruits')}>
If you log what register('fruits')
return you'll see a name
prop in there besides onChange
, onBlur
and ref
. If you add name={fruits.name}
to your select
you'll see watch
working too.
Edit: yes, this is missing from the documentation too at the moment.
Solution 2:[2]
You forgot to pass register()
props to Component. By passing {...fruits}
on select, it is working.
export default function App() {
const { register, watch } = useForm();
const fruits = register("fruits");
const myValue = watch("fruits", "default");
return (
<div className="App">
<h1>{myValue}</h1>
<select
onChange={(e) => {
fruits.onChange(e); // react hook form onChange
console.log("Here would go the my onChange"); // my onChange
}}
{...register('fruits')}
onBlur={fruits.onBlur}
ref={fruits.ref}
>
<option value="1Banana">Banana</option>
<option value="1Kiwi">Kiwi</option>
<option value="1Mango">Mango</option>
</select>
</div>
);
}
Solution 3:[3]
With a useState hook it's working link so:
e.target.value
is the selected value of your dropdown menu. To change your title dynamically you have to use a hook to serenader your component when the state changes.
See bellow:
import React from 'react';
import { useForm } from "react-hook-form";
import "./styles.css";
export default function App() {
const { register, watch } = useForm();
// const myValue = watch("fruits", "default");
const [myVal, setMyVal] = React.useState('Default')
const fruits = register("fruits");
return (
<div className="App">
<h1>{myVal}</h1>
<select
onChange={(e) => {
fruits.onChange(e);
setMyVal(e.target.value); // react hook form onChange
console.log("Here would go the my onChange"); // my onChange
}}
onBlur={fruits.onBlur}
ref={fruits.ref}
>
<option value="1Banana">Banana</option>
<option value="1Kiwi">Kiwi</option>
<option value="1Mango">Mango</option>
</select>
</div>
);
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Sergiu Paraschiv |
Solution 2 | Daryl Wong |
Solution 3 | GregMit |