ui: React error "uncontrolled input" in forms (demo repo provided)
Hi again Shadcn and congrats for continuing to improve your already awesome project!
I noticed that React throws the error A component is changing an uncontrolled input to be controlled when we start typing in a form input:
Here is a fresh Next.js project to which I added the example form provided in the doc: https://github.com/Zwyx/shadcn-ui-form-uncontrolled-input-demo
Simply start the project, open your browser’s console, and type in the form. You should see the error being thrown.
About this issue
- Original URL
- State: closed
- Created a year ago
- Reactions: 11
- Comments: 24 (4 by maintainers)
So, since
FormFieldis using a controlled component, you need to provide a default value for it. Otherwise React is seeing it going fromundefinedto a value.From the docs:
(Edit: I’ve update the example in the docs)
Thanks for this @tarikyildizci, helps get around the default values tripping zod for required inputs. This must be a very common problem, it’s the most basic implementation of a form, this should have more attention imo.
<Input {...field} type="number" min={0} value={field.value ?? ""} />this seems to resolve this issue, hook-form and zod still see the field.value, which is undefined, but the component recieves an empty string instead of undefined.
@dan5py I don’t want to set an arbitrary default value like 0…
I have a number input, so I can’t set the default value to an empty string. Any workaround for this?
I don’t really understand this behavior. I think it’s counter-intuitive to have a default value as a must in this case. I have a form and a select with multiple choices inside and I want to show the placeholder by default and not a selected value. Let’s say the selector is
genderand"male","female"… . I don’t want to specify a gender by default. But as my Form is used with my typeformSchemaanullvalue or empty string would cause a typescript error. And accepting that in my validator would cause my validation to allow null values which I don’t want. So to get rid of it I would need to set an enum value from gender, so “male” as a default value? How are you getting around this issue? Am I missing something?I’ve implemented numbers in Zod using the following:
This works with
z.input<typeof schema>andz.output<typeof schema>and the number fields will be properly typed. You can pass an empty string as a default value, and the form’s submission type will benumberforRequiredNumberornumber | ""for OptionalNumber.for hook-form, undefined, but the input is tricked into it being an empty string
And required_error of
z.string({required_error: "xxxx"})will only be triggered if the default isundefinedI used it to trigger
required_error