I want to provide default values in the input field using react-hook-form
. First I retrieve the user data from the API endpoint and then setting the state users
to that user data. Then I pass the state users
to the defaultValues
of useForm()
.
import React, { useState, useEffect } from "react";
import { useForm } from "react-hook-form";
import axios from "axios";
function LoginFile() {
const [users, setUsers] = useState(null);
useEffect(() => {
axios
.get("http://localhost:4000/users/1")
.then((res) => setUsers(res.data));
}, []);
useEffect(() => {
console.log(users);
}, [users]);
const { register, handleSubmit, errors } = useForm({
defaultValues: users,
});
return (
<div>
<form onSubmit={handleSubmit(onSubmit)}>
Email <input type="email" name="email" ref={register} /><br />
firstname <input name="firstname" ref={register} /><br/>
<input type="submit" />
</form>
</div>
);
}
export default LoginFile;
I did by the above code but didn't work as expected. All the input fields are still empty. I want to have some default values in the input field of my form.
The solution is to use the reset() function from the React Hook Form library, if you execute the function without any parameters ( reset() ) the form is reset to its default values, if you pass an object to the function it will set the form with the values from the object (e.g. reset({ firstName: 'Bob' }) ).
Solution: Writing an input with React hooks useInput() will accept an argument called opts , which will allow the developer to pass other input type of properties. Inside useInput() I will create a state hook that will contain the value of the input element and it will be updated onChange event listener .
The problem is that during the first render, users
is the useState
hook's initial value, which is null
. The value only changes after the axios.get()
request finishes, which is after the initial render. This means that the the default values passed to useForm
is null
.
The documentation for defaultValues says the following:
defaultValues
are cached on the first render within the custom hook. If you want to reset thedefaultValues
, you should use thereset
api.
So, you'll just need to use reset
to reset the form manually to the values which you fetch. The documentation for reset
says the following:
You will need to pass
defaultValues
touseForm
in order toreset
theController
components' value.
However, it's unclear from the documentation whether null
is enough as the defaultValues, or if you need to pass it a proper object with fields for each input. To play it safe, let's assume it's the latter.
The code for doing this would look something like this:
function LoginFile() {
const [users, setUsers] = useState({ email: "", firstname: "" });
const { register, handleSubmit, errors, reset } = useForm({
defaultValues: users,
});
useEffect(() => {
axios.get("http://localhost:4000/users/1").then((res) => {
setUsers(res.data);
reset(res.data);
});
}, [reset]);
useEffect(() => {
console.log(users);
}, [users]);
return (
<div>
<form onSubmit={handleSubmit(onSubmit)}>
Email <input type="email" name="email" ref={register} />
<br />
firstname <input name="firstname" ref={register} />
<br />
<input type="submit" />
</form>
</div>
);
}
Additionally, if the only reason for the useState hook is to store the value for defaultValues
, you don't need it at all and can clean up the code to be:
function LoginFile() {
const { register, handleSubmit, errors, reset } = useForm({
defaultValues: { email: "", firstname: "" },
});
useEffect(() => {
axios.get("http://localhost:4000/users/1").then((res) => {
reset(res.data);
});
}, [reset]);
return (
<div>
<form onSubmit={handleSubmit(onSubmit)}>
Email <input type="email" name="email" ref={register} />
<br />
firstname <input name="firstname" ref={register} />
<br />
<input type="submit" />
</form>
</div>
);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With