Issue
I am trying out React-Hook-form
The simple code for the checkbox is as below:
import React from 'react'
import { useForm } from 'react-hook-form'
export default function App() {
const {
register,
handleSubmit,
formState: { errors },
} = useForm()
const onSubmit = (data: any) => console.log(data)
console.log(errors)
return (
<div className='mx-auto justify-center p-32 flex'>
<form onSubmit={handleSubmit(onSubmit)}>
<div className='p-2'>
<label htmlFor=''>January</label>
<input
type='checkbox'
placeholder='January'
{...register('January', {})}
className='mx-3'
checked
/>
</div>
<div className='p-2'>
<label htmlFor=''>February</label>
<input
type='checkbox'
placeholder='February'
{...register('February', {})}
className='mx-3'
/>
</div>
<input type='submit' />
</form>
</div>
)
}
I can submit the form correctly but I have like the January checkbox to start off as a checked box but when I put 'checked' as shown in the code, I somehow could not 'uncheck' it.
I seem to be missing something and any help would be greatly appreciated.
Solution
The issue with passing checked is that it takes control away from useForm to manage the checkbox. useForm register() uses change handlers (onChange/onBlur) to update the checked (or value for non-checkboxes) attributes of the actual DOM <input> element.
By passing the checked prop you are overriding the checked DOM attribute that is managed by useForm. This causes the checkbox to be unable to change state.
Now that I've cleared up why this issue happens let's move on to the solution. This can be solved in two ways:
useFormallows you to pass a default values when you initially call the hook.const { register, handleSubmit, formState: { errors }, } = useForm({ defaultValues: { January: true } }); // ... <input type="checkbox" {...register("January")} />Or use the
defaultCheckedproperty of an<input type="checkbox" />this holds the initial checked value and doesn't override the current value likecheckeddoes.const { register, handleSubmit, formState: { errors }, } = useForm(); // ... <input type="checkbox" {...register("January")} defaultChecked />
Note that it's not a good idea to combine the two methods. Use one or the other. The useForm says the following in the defaultValues section:
The
defaultValuesprop populates the entire form with default values. It supports both synchronous and asynchronous assignment of default values. While you can set an input's default value usingdefaultValueordefaultChecked(as detailed in the official React documentation), it is recommended to usedefaultValuesfor the entire form.
In the given scenario it's probably better to use an array of selected values ["January", "March"] instead of an object { January: true, February: false, March: true }.
You can get the array result by using an (empty) array as the default value, and registering the checkboxes under the same name. If any values are present inside the array, they will be checked by default. The values used in the array will match the checkbox value property.
const {
register,
handleSubmit,
formState: { errors },
} = useForm({
defaultValues: { months: ["January"] }
// mark months as array and ^ check the checkbox with value "January"
});
// ...
// add the a `value` prop to the checkboxes
<input
type="checkbox"
value="January"
{...register("months")}
/>
<input
type="checkbox"
value="February"
{...register("months")}
/>
Answered By - 3limin4t0r
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.