我有一个3个字段,文本框,文本区域和文件输入形式。文本框和文本区域是必填字段和文件输入是可选的。
我使用react-hook-form,zod和zodResolver。
我添加了一个方案,并设置文件输入为可选的模式,但当我提交的形式没有选择一个文件,其显示错误。
我想显示的文件输入验证只有当一个文件被选中(即文件输入是可选的)
'use client'
import { z } from "zod";
import { useForm } from 'react-hook-form'
import { zodResolver } from "@hookform/resolvers/zod";
export default function Form() {
const MAX_FILE_SIZE = 2000000
const ACCEPTED_IMAGE_TYPES = [
'image/jpeg',
'image/jpg',
'image/png',
'image/webp',
]
const imageSchema = z.any()
// To not allow empty files
.refine((files) => files?.length >= 1, { message: 'Photo is required.' })
// To not allow files other than images
.refine((files) => ACCEPTED_IMAGE_TYPES.includes(files?.[0]?.type), {
message: '.jpg, .jpeg, .png and .webp files are accepted.',
})
// To not allow files larger than 5MB
.refine((files) => files?.[0]?.size <= MAX_FILE_SIZE, {
message: `Max file size is 2MB.`,
}).optional()
const baseSchema = z.object({
title: z.string().min(1, 'Title required').max(60, 'Maximum 60 characters.'),
message: z.string().min(1, 'Message required.').max(120, 'Maximum 120 characters.'),
image: imageSchema,
});
type FormValues = z.infer<typeof baseSchema>;
const { register, handleSubmit, control, watch, reset, formState: { errors, isSubmitting } } = useForm<FormValues>({
resolver: zodResolver(baseSchema),
});
//submit form
const onSubmit = async (data: any) => {
console.log(data);
}
return (
<div className="mx-auto max-w-md container">
<form onSubmit={handleSubmit(onSubmit)}>
<div className="py-8 p-10 bg-slate-100 border-slate-200 rounded-xl border-2">
<div className="mb-6">
<label className="text-gray-700 font-bold" htmlFor="name">Title</label>
<input type="text" {...register('title')} className="w-full border border-gray-300 py-2 pl-3 rounded mt-2 outline-none" />
{errors.title && <div className="text-red-500">{errors.title?.message}</div>}
</div>
<div className="mb-6">
<div className="mb-6">
<label className="text-gray-700 font-bold" htmlFor="name">Message</label>
<textarea rows={4} {...register('message')} className="w-full border border-gray-300 py-2 pl-3 rounded mt-2 outline-none" />
{(errors as any).message && <div className="text-red-500">{(errors as any).message?.message}</div>}
</div>
</div>
<div className="mb-6">
<label className="text-gray-700 font-bold" htmlFor="name">Photo <span className="text-sm font-normal text-gray-700"> (optional)</span> </label>
<input type="file" {...register('image')} className="w-full border border-gray-300 py-2 pl-3 rounded mt-2 outline-none" />
{errors.image && <div className="text-red-500">{errors.image?.message?.toString()}</div>}
</div>
<button disabled={isSubmitting} type="submit" className="disabled:opacity-50 w-full mt-6 text-indigo-50 font-bold bg-indigo-600 py-3 rounded-md hover:bg-indigo-500"><span> Submit</span></button>
</div>
</form>
</div>
)
}
字符串
1条答案
按热度按时间6uxekuva1#
问题出在imageSchema中。我更新了图像架构,它按预期工作
字符串