ui
ui copied to clipboard
Unable to reset the Select component with React Hook Form
Calling form.reset()
(React Hook Form reset method) does not reset the value selected by the user in the Select
.
Here's my useForm
hook usage:
const form = useForm<z.infer<typeof someSchema>>({
resolver: zodResolver(someSchema),
})
Here's my submit handler:
async function onSubmit(values: z.infer<typeof someSchema>) {
form.reset()
}
Here's my Select field:
<Form {...form}>
<form
onSubmit={form.handleSubmit(onSubmit)}
>
<FormField
control={form.control}
name="type"
render={({ field }) => (
<FormItem>
<FormLabel>Type</FormLabel>
<Select onValueChange={field.onChange} defaultValue={field.value}>
<FormControl>
<SelectTrigger>
<SelectValue placeholder="Select something" />
</SelectTrigger>
</FormControl>
<SelectContent>
<SelectItem value="A">
A
</SelectItem>
<SelectItem value="B">
B
</SelectItem>
</SelectContent>
</Select>
</FormItem>
)}
/>
<Button type="submit">
Submit
</Button>
</form>
</Form>
i think you need to pass defaulValues
form.reset(defaultValues)
Thanks @jl-calda. I had tried this way as well and still got the same result.
const defaultValues = {
type: undefined,
}
// ...
form.reset(defaultValues);
Try setting it up like this
const form = useForm<z.infer<typeof someSchema>>({
resolver: zodResolver(someSchema),
defaultValues: {
type: "A"
}
})
If you want to have also unset state, so there is option A,B or not selected, you can make "type" nullable in your zod schema and set defaultValue to null.
Then just call reset() without providing any parameters if you want to reset whole form
Try setting it up like this
const form = useForm<z.infer<typeof someSchema>>({ resolver: zodResolver(someSchema), defaultValues: { type: "A" } })
If you want to have also unset state, so there is option A,B or not selected, you can make "type" nullable in your zod schema and set defaultValue to null.
Then just call reset() without providing any parameters if you want to reset whole form
I tried doing this and I does reset the values
however it doesn't the entered value on the input field
resulting in something like this
Hey guys, there is a bug in Radix if you want to reset the value and show the placeholder again. It was fixed in https://github.com/radix-ui/primitives/pull/2174 and you can reset to placeholder using ""
. For now, it's only available on RC https://www.npmjs.com/package/@radix-ui/react-select?activeTab=versions
I also encountered such a problem, my code is:
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
content: "",
},
})
I used form.reset()
and it didn't work. 😢
@evanlong0926 Did you install the RC? v2.0.0-rc.7
@evanlong0926 Did you install the RC?
v2.0.0-rc.7
No, I only have the Textarea
component in my form
.
Try setting it up like this
const form = useForm<z.infer<typeof someSchema>>({ resolver: zodResolver(someSchema), defaultValues: { type: "A" } })
If you want to have also unset state, so there is option A,B or not selected, you can make "type" nullable in your zod schema and set defaultValue to null. Then just call reset() without providing any parameters if you want to reset whole form
I tried doing this and I does reset the values however it doesn't the entered value on the input field resulting in something like this
Can you provide som code?
I have installed the npm i @radix-ui/[email protected]
but it still cannot reset the Select in Form Component,
Can anyone suggest a solution for me?
My Select Option cannot be null
same problem
I have installed the npm i @radix-ui/[email protected]
but it still cannot reset the Select in Form Component,
Can anyone suggest a solution for me?
My Select Option cannot be null
@apexbb Are you resetting to ""
? If so and still having issues, can you provide a minimal sandbox? Thansk!
Try using value
instead of defaultValue
-<Select onValueChange={field.onChange} defaultValue={field.value}>
+<Select onValueChange={field.onChange} value={field.value}>
Try using
value
instead ofdefaultValue
-<Select onValueChange={field.onChange} defaultValue={field.value}> +<Select onValueChange={field.onChange} value={field.value}>
I have tried this and setting the defaultValues
to undefined
. When form.reset()
is called, the <Select value={field.value}>
doesn't reset back to the original where the <SelectValue placeholder='Select a role'>
.
Any movement on this? All of these suggestions don't work as expected. Just like @dejongyeong stated, if you have the default value declared as an empty string while passing the value
prop the default placeholder gets overwritten by the empty string.
As a temporary workaround, I have modified the SelectTrigger
to explicitly check the field.value
. If it is not set, it displays your placeholder.
<FormItem>
<FormLabel>Size</FormLabel>
<Select
onValueChange={field.onChange}
defaultValue={field.value}
+ value={field.value}
>
<FormControl>
<SelectTrigger>
+ {field.value ? <SelectValue placeholder="Select size" /> : "Select size"}
</SelectTrigger>
</FormControl>
<SelectContent>
<SelectGroup>
<SelectLabel>Size</SelectLabel>
<SelectItem value="small">
Small
</SelectItem>
<SelectItem value="medium">
Medium
</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
You also need to add the value
prop to the Select
component, as @riyaadh-abrahams suggested, in order to clear the selection when calling form.reset()
.
As @joaom00 said, you need to upgrade to @radix-ui/[email protected]. I got the desired behavior by setting the default value to ""
and adding value={field.value}
to the Select.
To set the default value to ""
, we would have to allow it as a valid value in our schema right? In which case, how can we ensure that the empty string ""
throws a validation error for the Select
field?
To set the default value to
""
, we would have to allow it as a valid value in our schema right? In which case, how can we ensure that the empty string""
throws a validation error for theSelect
field?
You can do something like z.string().trim().min(1, ( message: "required" })
for string values or .refine()
for more complex cases
As @joaom00 said, you need to upgrade to @radix-ui/[email protected]. I got the desired behavior by setting the default value to
""
and addingvalue={field.value}
to the Select.
Thank you for this very simple yet effective fix.
As a temporary workaround, I have modified the
SelectTrigger
to explicitly check thefield.value
. If it is not set, it displays your placeholder.<FormItem> <FormLabel>Size</FormLabel> <Select onValueChange={field.onChange} defaultValue={field.value} + value={field.value} > <FormControl> <SelectTrigger> + {field.value ? <SelectValue placeholder="Select size" /> : "Select size"} </SelectTrigger> </FormControl> <SelectContent> <SelectGroup> <SelectLabel>Size</SelectLabel> <SelectItem value="small"> Small </SelectItem> <SelectItem value="medium"> Medium </SelectItem> </SelectGroup> </SelectContent> </Select>
You also need to add the
value
prop to theSelect
component, as @riyaadh-abrahams suggested, in order to clear the selection when callingform.reset()
.
The issue still not fix as of today and this workaround works for me. Thank you so much.
Same issue. I need the select field to be empty by default but in zod it's required. I don't want to have a "not_selected" option or something.
Anybody with a solution to this form reset issue?
<FormField
control={form.control}
name='furniture'
render={({ field }) => {
return (
<FormItem>
<FormLabel>Nội thất</FormLabel>
<Select
onValueChange={(value) =>
value && field.onChange(value)
}
value={field.value}
>
<FormControl>
<SelectTrigger>
<SelectValue />
</SelectTrigger>
</FormControl>
<SelectContent>
{Object.values(furniture).map((item) => (
<SelectItem value={item.key} key={item.key}>
{item.name}
</SelectItem>
))}
</SelectContent>
</Select>
</FormItem>
)
}}
/>
I found the problem caused by the onValueChange
event inside the form. Try to modify onChangeValue
and use value
instead of defaultValue
Would be great if this was fixed
As a temporary workaround, I have modified the
SelectTrigger
to explicitly check thefield.value
. If it is not set, it displays your placeholder.<FormItem> <FormLabel>Size</FormLabel> <Select onValueChange={field.onChange} defaultValue={field.value} + value={field.value} > <FormControl> <SelectTrigger> + {field.value ? <SelectValue placeholder="Select size" /> : "Select size"} </SelectTrigger> </FormControl> <SelectContent> <SelectGroup> <SelectLabel>Size</SelectLabel> <SelectItem value="small"> Small </SelectItem> <SelectItem value="medium"> Medium </SelectItem> </SelectGroup> </SelectContent> </Select>
You also need to add the
value
prop to theSelect
component, as @riyaadh-abrahams suggested, in order to clear the selection when callingform.reset()
.
Hi,
Is there any progress on this? I'm rendering my select values enforced by a nativeEnum by zod, which is dictated by a Prisma enum. I can only set the default value on the form as undefined, I cannot pass "" (empty string) as a default value.
The above workaround works in displaying the placeholder value, the only issue is that the previous value is still checked (Check Icon).
Is there anyway to remove the check at reset?
As a temporary workaround, I have modified the
SelectTrigger
to explicitly check thefield.value
. If it is not set, it displays your placeholder.<FormItem> <FormLabel>Size</FormLabel> <Select onValueChange={field.onChange} defaultValue={field.value} + value={field.value} > <FormControl> <SelectTrigger> + {field.value ? <SelectValue placeholder="Select size" /> : "Select size"} </SelectTrigger> </FormControl> <SelectContent> <SelectGroup> <SelectLabel>Size</SelectLabel> <SelectItem value="small"> Small </SelectItem> <SelectItem value="medium"> Medium </SelectItem> </SelectGroup> </SelectContent> </Select>
You also need to add the
value
prop to theSelect
component, as @riyaadh-abrahams suggested, in order to clear the selection when callingform.reset()
.
thank you so much ❤️
react hook form reset has bug !
use form.reset
, form can't rerender select. so u can see it not working.
but form.setValue
can working and rerender.
and how to use it for 100% working
just like this
reset single form item
const onReset = (name: string) => form.setValue(name, "");
reset all form item
import { useFormContext, UseFormReturn } from "react-hook-form";
export const useReset = (form?: UseFormReturn<any>) => {
const formctx = useFormContext();
const { getValues, setValue } = form ?? formctx;
const fields = Object.keys(getValues());
fields.forEach((field) => setValue(field, ""));
};
Hi! I had the same issue but someone on Stackoverflow suggested I make this change, which seems to have worked for me.
https://stackoverflow.com/questions/69548100/react-hook-form-and-react-select-not-working-as-expected
<FormField
control={form.control}
name='furniture'
render={({ field }) => {
return (
<FormItem>
<FormLabel>Nội thất</FormLabel>
<Select
- onValueChange={(value) =>
- value && field.onChange(value)
- }
+ {...field}
>
<FormControl>
<SelectTrigger>
<SelectValue />
</SelectTrigger>
</FormControl>
<SelectContent>
{Object.values(furniture).map((item) => (
<SelectItem value={item.key} key={item.key}>
{item.name}
</SelectItem>
))}
</SelectContent>
</Select>
</FormItem>
)
}}
/>
Hi! I had the same issue but someone on Stackoverflow suggested I make this change, which seems to have worked for me.
https://stackoverflow.com/questions/69548100/react-hook-form-and-react-select-not-working-as-expected
Hello! I tried it and it works. But now I have an error in the console browser:
Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()? Check the render method of 'Controller'.