ファイルのアップロード
ファイルアップロードを扱うには、フォームの encType 属性を multipart/form-data
に設定し、メソッドは POST
である必要があります。
#構成
ファイル input の設定は、他の input と何ら変わりません。
1import { useForm } from '@conform-to/react';
2import { parseWithZod } from '@conform-to/zod';
3import { z } from 'zod';
4
5const schema = z.object({
6 profile: z.instanceof(File, { message: 'Profile is required' }),
7});
8
9function Example() {
10 const [form, fields] = useForm({
11 onValidate({ formData }) {
12 return parseWithZod(formData, { schema });
13 },
14 });
15
16 return (
17 <form method="POST" encType="multipart/form-data" id={form.id}>
18 <div>
19 <label>Profile</label>
20 <input type="file" name={fields.profile.name} />
21 <div>{fields.profile.error}</div>
22 </div>
23 <button>Upload</button>
24 </form>
25 );
26}
#複数のファイル
複数のファイルをアップロードできるようにするには、ファイル入力に multiple 属性を設定する必要があります。フィールドメタデータのエラーが各ファイルのすべてのエラーを含んでいない可能性があることに注意することが重要です。 yup および zod からのエラーは、対応するパスに基づいてマッピングされ、各選択のエラーは、配列自体(例: files
)ではなく、対応するインデックス(例: files[0]
)にマッピングされます。すべてのエラーを表示したい場合は、フィールドメタデータの allErrors プロパティを代わりに使用することを検討できます。
1import { useForm } from '@conform-to/react';
2import { parse } from '@conform-to/zod';
3import { z } from 'zod';
4
5const schema = z.object({
6 files: z
7 .array(
8 z
9 .instanceof(File)
10 .refine((file) => file.size < 1024, 'File size must be less than 1kb'),
11 )
12 .min(1, 'At least 1 file is required')
13 .refine(
14 (files) => files.every((file) => file.size < 1024),
15 'File size must be less than 1kb',
16 ),
17});
18
19function Example() {
20 const [form, fields] = useForm({
21 onValidate({ formData }) {
22 return parseWithZod(formData, { schema });
23 },
24 });
25
26 return (
27 <form method="POST" encType="multipart/form-data" id={form.id}>
28 <div>
29 <label>Mutliple Files</label>
30 <input type="file" name={fields.files.name} multiple />
31 <div>{Object.values(fields.files.allErrors).flat()}</div>
32 </div>
33 <button>Upload</button>
34 </form>
35 );
36}