trpcは基本json形式のみしか送受信は対応していませんが、
experimentalでFormDataが2023/04頃に対応されているため、やってみた。
※主な用途としては画像のアップロードなどで必要になると思います。
公式のサンプル
基本はサンプル通りだがzod-form-data
が結構やっかい
https://www.npmjs.com/package/zod-form-data
以下の例のようなシンプルなものならいいが、挙げられていない型の例を書いてみる
import { zfd } from 'zod-form-data';
if (typeof window === 'undefined') {
const undici = require('undici');
globalThis.File = undici.File as any;
}
export const uploadFileSchema = zfd.formData({
name: zfd.text(),
image: zfd.file(),
});
booleanはundefinedの場合にfalse、trueは任意の文字列に変更できる
https://www.npmjs.com/package/zod-form-data#checkbox
objectの場合はzodを使いつつzfdで中身を定義していく
const TestSchema = zfd.formData({
optionalText: zfd.text().optional(),
booleanData: zfd.checkbox({ trueValue: 'true' }),
stringArray: zfd.repeatable(z.array(zfd.text())),
objectArray: zfd.repeatable(z.array(XXXSchema)),
});
const XXXSchema = z.object({
text: zfd.text(),
file: zfd.file(z.instanceof(File).optional()),
});
React側での送信イメージ
const formMutate = trpc.testForm.useMutation();
const submit = () => {
const formData = new FormData();
formData.append('name', name);
if (optionalText) {
formData.append('optionalText', optionalText);
}
if (image.file) {
formData.append('file', image.file, image.file.name);
}
formMutate.mutate(formData);
};