🐶
RemixからReactRouter7へファイルアップロードの方法も移行する
React Router 7(以下RR7)はReact Routerの最新バージョンであるだけでなく、Remixのv3でもあります。この辺りは公式のブログで説明されています。
つまり、Remix v2の移行先は(イヤじゃなければ)RR7になります。
しかしRemixにあったAPIが一部削除されています。
Removed APIs
The following APIs have been removed in React Router v7:
json
defer
unstable_composeUploadHandlers
unstable_createMemoryUploadHandler
unstable_parseMultipartFormData
このunstable
とついてるAPIは主にファイルアップロードに関するものですが、公式の移行ドキュメントでは触れられてないので、ここで代替手段を書きたいと思います。
Remixでの書き方
移行の前にRemixでの書き方です。自分の環境ではこうなってました。
multipart/form-data
で送られてきた画像を処理する感じです。
import {
type ActionFunctionArgs,
unstable_createMemoryUploadHandler,
unstable_parseMultipartFormData,
} from "@remix-run/node";
export async function action({ request, params, context }: ActionFunctionArgs) {
const uploadHandler = unstable_createMemoryUploadHandler({
maxPartSize: 1024 * 1024 * 3,
});
const form = await unstable_parseMultipartFormData(
request,
uploadHandler,
);
const file = form.get("file");
// Save method
}
RR7での書き方
RR7公式ドキュメントの"File Uploads"を参照します。
まず、公式が推奨しているライブラリを導入します。
npm i @mjackson/form-data-parser
そして上のコードを書き換えます。
import { parseFormData, FileUpload } from "@mjackson/form-data-parser";
export async function action({ request, params, context }: ActionFunctionArgs) {
const uploadHandler = async (fileUpload: FileUpload) => {
if (fileUpload.fieldName === "file") {
// File を返す
}
};
const form = await parseFormData(
request,
uploadHandler, // もしくはundefined
{ maxFileSize: 1024 * 1024 * 3 }
);
const file = form.get("file");
// Save method
}
この場合、ファイルサイズ制限はparseFormData
の方でやるので、uploadHandler
の部分はundefined
でも問題なく動作しました。
おわりに
このunstable
がつくAPIはRemix公式のファイルアップロードのドキュメントで使われているので、おそらく多くの環境で使われてるんじゃないかと思います。しかし移行ドキュメントに載ってなかったので書いてみました。
Discussion