MSWの初期化タイミング問題と解決方法
Next.js
React
MSW
知識
MSW (Mock Service Worker)でハンドラーが動作しない原因の一つである、初期化タイミングの問題とその解決方法。
問題の内容
useEffect内でMSWを非同期初期化しているが、その完了を待たずにアプリがレンダリングされるため、初回のAPIリクエストがMSWを通らず実際のAPIサーバーに送信されてしまう。
問題のあるコード
typescript
useEffect(() => {
void import('@/mocks').then(({ initMocks }) => {
void initMocks(); // 非同期実行、完了を待たない
});
}, []);
// MSWの準備完了前にレンダリングされる
return <QueryClientProvider>{children}</QueryClientProvider>;解決方法
MSWの初期化完了を状態管理し、準備完了後にのみアプリをレンダリングする。
typescript
const [initializedMSW, setInitializedMSW] = useState(false);
useEffect(() => {
if (process.env.NEXT_PUBLIC_ENABLE_MSW === 'true') {
void (async () => {
const { initMocks } = await import('@/mocks');
await initMocks();
setInitializedMSW(true); // 初期化完了を記録
})();
} else {
setInitializedMSW(true); // MSW不要の場合は即座に準備完了
}
}, []);
// MSW準備完了後にのみレンダリング
return initializedMSW ? (
<QueryClientProvider>{children}</QueryClientProvider>
) : null;ポイント
- 非同期処理の完了を
useStateで管理 - 初期化中は
nullを返してレンダリングを遅延 - 環境変数でMSWの有効/無効を制御し、無効時は即座にレンダリング