はじめに
この記事では、useCallbackフックとuseSWRを組み合わせて、Reactアプリケーションのデータフェッチを最適化する方法を紹介します。
そもそもuseCallbackとuseSWRって誰?
useCallback
useCallbackフックは依存配列に含んだ値が変更されたときにのみ関数を再作成するためのHooksです。これにより、不要な関数の再定義を防ぎます。
useSWR
useSWRは、Reactでデータのフェッチとキャッシングを簡単に行うためのHooksを提供するライブラリです。
フェッチしたデータのキャッシュや、古くなったデータを自動でフェッチしてくれたり、他にも色々な便利な機能を提供してくれます。
実装例の解説
以下のコードはuseCallback
とuseSWR
を組み合わせて、データ取得部分を実装しています。
fetcher関数の定義
ここでは、useCallback
内でfetcher関数を定義することでメモ化し、依存関係(integration
とdate
)が変更されたときのみ再作成されることを保証します。
const fetcher = useCallback(async () => {
// データ取得
const getData = (
await fetch(`/analytics/${integration.id}?date=${date}`)
).json();
return getData;
}, [integration, date]);
useSWRによるデータフェッチ
useSWRを使用してデータフェッチを管理し、キーとメモ化されたfetcher関数で設定します。
const { data } = useSWR(`/analytics-${integration?.id}-${date}`, fetcher, {
refreshInterval: 0,
refreshWhenHidden: false,
revalidateOnFocus: false,
revalidateOnReconnect: false,
revalidateIfStale: false,
refreshWhenOffline: false,
revalidateOnMount: true,
});
useCallback
でfetcher()
関数をラップすることで、その依存関係(integration
とdate
)が変更されたときのみ再作成されることを保証します。
fetcher関数のメモ化により、useSWR
はfetcher関数がintegrationまたはdateが変更されない限り変更されていないと認識し、不要な再フェッチを防ぎます。
useCallbackなしの場合の問題点
Reactにおける関数の参照
Reactでは、コンポーネントが再レンダリングされるたびに、その中で定義されたすべての関数が再作成されます。
つまりuseCallback
を使用しないと、再レンダリングごとに新しいインスタンスのfetcher関数が作成されます。
useSWRへの影響
useSWR
はデータを識別するためのキーと、fetcher関数の参照に依存しています。
参照が変わるとuseSWR
はfetcher関数のロジックが変更されていなくてもデータを再フェッチする必要があると解釈する可能性があります。
const fetcher = async () => {
// データ取得
const getData = (
await fetch(`/analytics/${integration.id}?date=${date}`)
).json();
return getData;
};
上記の実装の場合、再レンダリングごとに新しいfetcher関数が作成されます。
その為useSWR
は毎回異なる関数参照を見てしまい、integration
やdate
が変更されていなくても不要な再フェッチが発生する可能性があります。
まとめ
重要ポイントの復習
- useCallbackは関数をメモ化し、不要な再作成を防ぐ。
- useSWRはデータフェッチを管理し、関数参照の安定性に依存する。
最後に
useCallback
とuseSWR
を組み合わせることで、React製のアプリケーションのデータフェッチを最適化し、パフォーマンスを向上させることができます。