Best way to handle file input with react hook from zod in nextjs
Unanswered
Sai-Kolli posted this in #help-forum
Hi guys can some one suggest best way to handle file inputs with react-hook-form and zod i am using shadcn for ui components.
my requirement is allow user to upload multiple images and i want to include validation for that field and i want to upload this images to storage only after submitting the form instead of uploading when ever they added images
here is my zod schema
my requirement is allow user to upload multiple images and i want to include validation for that field and i want to upload this images to storage only after submitting the form instead of uploading when ever they added images
here is my zod schema
export const addProductSchema = z.object({ brandName: z.string().min(1).max(255), productName: z.string().min(1).max(255), description: z .string() .min(1) .max(255) .default( "lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam, voluptatum! " ), price: z.coerce.number().min(1).max(1000000), discount: z.coerce.number().min(1).max(100), sizes: z.array( z.object({ size: z.string(), quantity: z.coerce.number(), }) ), images: z.instanceof(FileList), });
Here is My defaultValues for the useForm hook
images: new FileList(),
here is my FormField<FormField name="images" control={form.control} defaultValue={form.getValues("images")} render={({ field }) => ( <FormItem> <FormLabel>Images</FormLabel> <FormControl> <Input multiple type="file" onChange={(e) => { const files = e.target.files; if (files) { form.setValue("images", files); } }} /> </FormControl> <FormMessage /> </FormItem> )} />
please help me with this
Thank you.
11 Replies
@Sai-Kolli Hi guys can some one suggest best way to handle file inputs with react-hook-form and zod i am using shadcn for ui components.
my requirement is allow user to upload multiple images and i want to include validation for that field and i want to upload this images to storage only after submitting the form instead of uploading when ever they added images
here is my zod schema
> `export const addProductSchema = z.object({
> brandName: z.string().min(1).max(255),
> productName: z.string().min(1).max(255),
> description: z
> .string()
> .min(1)
> .max(255)
> .default(
> "lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam, voluptatum! "
> ),
> price: z.coerce.number().min(1).max(1000000),
> discount: z.coerce.number().min(1).max(100),
> sizes: z.array(
> z.object({
> size: z.string(),
> quantity: z.coerce.number(),
> })
> ),
> images: z.instanceof(FileList),
> });`
>
> Here is My defaultValues for the useForm hook
> images: new FileList(),
>
>
> here is my FormField
>
> `<FormField
> name="images"
> control={form.control}
> defaultValue={form.getValues("images")}
> render={({ field }) => (
> <FormItem>
> <FormLabel>Images</FormLabel>
> <FormControl>
> <Input
> multiple
> type="file"
> onChange={(e) => {
> const files = e.target.files;
> if (files) {
> form.setValue("images", files);
> }
> }}
> />
> </FormControl>
>
> <FormMessage />
> </FormItem>
> )}
> />`
>
>
> please help me with this
>
> Thank you.
I usually do this
const MAX_FILE_SIZE = 500000;
const ACCEPTED_IMAGE_TYPES = ["image/jpeg", "image/jpg", "image/png", "image/webp"];
const RegistrationSchema = z.object({
profileImage: z
.any()
.refine((files) => files?.length == 1, "Image is required.")
.refine((files) => files?.[0]?.size <= MAX_FILE_SIZE, `Max file size is 5MB.`)
.refine(
(files) => ACCEPTED_IMAGE_TYPES.includes(files?.[0]?.type),
".jpg, .jpeg, .png and .webp files are accepted."
),
});tq so much @Ray for helping and i like this approach but still i have a problem of resetting the field after the sumbission
Here is the field
remaining fields working fine
const form = useForm<AddProductSchemaType>({
resolver: zodResolver(addProductSchema),
defaultValues: {
brandName: "",
productName: "",
description: "",
price: 0,
discount: 0,
images: [],
sizes: [
{ size: "S", quantity: 0 },
{ size: "M", quantity: 0 },
{ size: "L", quantity: 0 },
],
},
});Here is the field
<FormField
name="images"
control={form.control}
defaultValue={[]}
render={({ field }) => (
<FormItem>
<FormLabel>Images</FormLabel>
<FormControl>
<Input
multiple
type="file"
onChange={(e) => {
const files = e.target.files;
if (files) {
form.setValue("images", files);
}
}}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>remaining fields working fine
onSubmit handler
const onSubmit = async (data: AddProductSchemaType) => {
console.log("formData", data);
alert(JSON.stringify(data));
form.reset();
};you could create a ref for the form and use
ref.current?.reset() after the actionI initialized useForm hook to form
reset method is from react-hook-form returned by useForm hook
ah ok then
form.reset() should do itdid you mean the field get reset but not the image field?
yes bro all are resetting except that image field whatever the images we selected still remains same. only on refresh it was working
try
form.setValue("images", []); after form.reset()