RemixのLoader関数の共通化について
解決したいこと
RemixにおけるLoader関数の設計について教えて頂きたいです。
Remixでは各ルーティングごとにLoader関数を定義しますが、一部の処理は同じロジックになるため、共通化を検討しています。
私は共通する処理を別ディレクトリに格納して呼び出す設計で作成しました。
Loader関数の共通化について、実際の仕事ではどのように設計しているか?などのアドバイスをいただきたいです。
よろしくお願いいたします。
↓作りかけですが、Githubはこちらです。
https://github.com/dbd-fish/react_sample
対象コード
↓Loader関数
sample_remix_react/app/routes/mypage.tsx
import { LoaderFunction, redirect } from '@remix-run/node';
import { userDataLoader } from '../loader/userDataLoader';
import {
AuthenticationError,
authTokenLoader,
} from '../loader/authTokenLoader';
export const loader: LoaderFunction = async ({ request }) => {
try {
await authTokenLoader(request);
const userData = await userDataLoader(request);
return new Response(JSON.stringify(userData), {
headers: { 'Content-Type': 'application/json' },
});
} catch (error) {
if (error instanceof AuthenticationError) {
console.log('Loader: AuthenticationError:');
return redirect('/login');
}
console.error('Loader Error:', error);
throw new Response('ユーザーデータの取得に失敗しました。', {
status: 400,
});
}
};
export default function MyPage() {
// 省略
}
↓Loader関数から呼び出す共通処理authTokenLoader()
sample_remix_react/app/loader/authTokenLoader.tsx
export class AuthenticationError extends Error {
constructor(message: string) {
super(message);
this.name = 'AuthenticationError';
}
}
export async function authTokenLoader(request: Request) {
// HTTP-only クッキーの取得
const cookieHeader = request.headers.get('Cookie');
console.log('Loader: Incoming cookies:', cookieHeader);
// authToken と csrfToken をクッキーから抽出
const authTokenMatch = cookieHeader?.match(/authToken=([^;]+)/);
const csrfTokenMatch = cookieHeader?.match(/csrftoken=([^;]+)/);
const authToken = authTokenMatch ? authTokenMatch[1] : null;
const csrfToken = csrfTokenMatch ? csrfTokenMatch[1] : null;
console.log('Loader: Extracted authToken:', authToken);
console.log('Loader: Extracted csrfToken:', csrfToken);
// authToken が存在しない場合はログインページへリダイレクト
if (!authToken) {
console.log('Loader: Missing authToken, redirecting to login.');
throw new AuthenticationError('認証トークンが見つかりません。');
}
return;
}
↓Loader関数から呼び出す共通処理userDataLoader()
sample_remix_react/app/loader/userDataLoader.tsx
import { fetchUserData } from '../utils/api/fetchUserData';
export async function userDataLoader(request: Request) {
// 外部API呼び出し
console.log('Loader: Fetching user data with authToken...');
const userData = await fetchUserData(request);
console.log('Loader: Retrieved user data:', userData);
return userData;
}
0