🔄
【Remix】loaderとactionについて
はじめに
新しい案件ではremixを使っていました。
その際に既存メンバーから「loader勉強しといて」と言われました。
loaderとは何か、付随してactionとは何か学んでみました。
mvにもloaderとactionが書かれています。
- remix LP
サイトかっこいい、、、
翻訳して読みました。
https://remix.run/
loaderとは
loaderは、ページのレンダリング前にサーバーサイドでデータを取得するための機能です。
主に以下のような用途で使用されます。
- APIからのデータ取得
- データベースからの情報取得
- 認証状態の確認
基本的な使い方
下記loaderの実装例です。
ここでは現在時刻を取得して表示しています。
loaderの戻り値を型で指定することでtype safetyに実装できます。
import type { LoaderFunction } from "@remix-run/node";
import { useLoaderData } from "@remix-run/react";
// データの型定義
type LoaderData = {
message: string;
timestamp: string;
};
// loaderの実装
export const loader: LoaderFunction = async () => {
const data: LoaderData = {
message: "loader sample",
timestamp: new Date().toISOString()
};
return data;
};
// loaderのデータをuseLoaderDataで取得する
export default function LoaderExample() {
const data = useLoaderData<LoaderData>();
return (
<div>
<h1>Loader サンプル</h1>
<p>{data.message}</p>
<p>現在時刻: {data.timestamp}</p>
</div>
);
}
Reactとの違い
loaderを使用することで、従来のReactと比べて以下のような利点があります。
1. データフェッチの最適化
- Reactでは通常useEffectでデータを取得するため、クライアントサイドでのフェッチが必要
- loaderはサーバーサイドで実行されるため、初期表示が高速
- ウォーターフォール問題(データ取得の連鎖)を防げる
2. 型安全性の向上
- loaderの戻り値の型を定義することで、コンポーネント内でのデータ使用時に型の補完が効く
- useLoaderDataによって型安全にデータにアクセス可能
3. エラーハンドリングの統一
- Reactではtry-catchを各コンポーネントで実装する必要がある
- loaderではエラーバウンダリー(Reactのコンポーネントツリー内でエラーが発生した際に、そのエラーをキャッチして代替のUIを表示する機能)と連携して集中的にエラー処理が可能
4. SEO対策
- サーバーサイドでデータを取得するため、SEO対策が可能
- 初期HTMLにデータが含まれる
5. 開発体験の向上
- データ取得ロジックがルートモジュールに集中するため、見通しが良い
- コンポーネントの責務が明確になる
実案件での使用
私が実案件で使用した際にはmicroCMSでapiを作成し、データをloaderで取得して使用しました。
loaderでtextや画像を取得してblogを作成しました。
下記関連記事になります。
actionとは
actionは、フォーム送信やデータの更新などのPOST、PUT、DELETE操作を処理するための機能です。
主に以下のような用途で使用されます。
- フォームデータの送信
- データベースの更新
- ファイルのアップロード
基本的な使い方
下記actionの実装例です
import type { ActionFunction } from "@remix-run/node";
import { Form } from "@remix-run/react";
// actionの実装
export const action: ActionFunction = async ({ request }) => {
const formData = await request.formData();
// nameと連動している 合わせないと返却値がnullになる
const message = formData.get("message");
console.log("受け取ったメッセージ:", message);
// リダイレクトや新しいデータの返却が可能
return { success: true };
};
export default function LoaderExample() {
return (
<div>
{/* Formコンポーネントを使用してPOSTリクエストを送信 */}
<Form method="post">
<input type="text" name="message" placeholder="メッセージを入力" />
<button type="submit">送信</button>
</Form>
</div>
);
}
実行
上記のコードを実行すると画面上に下記のようなformが表示されます。
サーバー上にlogを出すとこのようにformに入力されたメッセージが表示されます。
loaderとactionの使い分け
- loaderは読み取り専用の操作に使用
- actionはデータの更新を伴う操作に使用
エラーハンドリング
loaderとactionでは、適切なエラーハンドリングを実装することが重要です。
export const loader: LoaderFunction = async () => {
try {
const data = await fetchSomeData();
return json({ data });
} catch (error) {
throw new Response("データの取得に失敗しました", { status: 500 });
}
};
まとめ
- loaderはページ表示前のデータ取得に使用
- actionはフォーム送信などのデータ更新に使用
- 適切なエラーハンドリングの実装が重要
- TypeScriptと組み合わせることで型安全な実装が可能
remixを触る上で基本的な部分になるので抑えておきたい。
Discussion