React Query: 効率的なデータ共有と更新
React Query は、React アプリケーションでのデータフェッチングと状態管理を簡素化する強力なライブラリです。その特徴的な機能の一つに、異なるコンポーネント間でのデータ共有があります。この記事では、同じクエリキーを使用することで、どのようにして効率的にデータを共有し、更新できるかを一般的な例を用いて説明します。
キーポイント
- 同じクエリキーを使用すると、React Query は内部的に同じキャッシュを共有します。
- 一方のコンポーネントで自動再フェッチを設定すると、共有しているすべてのコンポーネントにデータが反映されます。
- これにより、アプリケーション全体でのデータの一貫性が保たれ、パフォーマンスも向上します。
実装例
以下に、ユーザー一覧ページとヘッダーコンポーネントで同じユーザーデータを共有する例を示します。
API関数(src/api/users.js)
export const fetchUsers = async () => {
const response = await fetch('https://api.example.com/users');
if (!response.ok) {
throw new Error('Failed to fetch users');
}
return response.json();
};
ユーザー一覧ページのコンポーネント(src/components/UserListPage.js)
import React from 'react';
import { useQuery } from '@tanstack/react-query';
import { fetchUsers } from '../api/users';
export const UserListPage = () => {
const { data: users, isLoading, error } = useQuery({
queryKey: ['users'],
queryFn: fetchUsers,
});
if (isLoading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
return (
<ul>
{users.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
};
ヘッダーコンポーネント(src/components/Header.js)
import React from 'react';
import { useQuery } from '@tanstack/react-query';
import { fetchUsers } from '../api/users';
export const Header = () => {
const { data: users } = useQuery({
queryKey: ['users'],
queryFn: fetchUsers,
refetchInterval: 60000, // 1分ごとに再フェッチ
});
const userCount = users ? users.length : 0;
return (
<header>
<h1>My App</h1>
<p>Total Users: {userCount}</p>
</header>
);
};
動作の説明
- 両方のコンポーネントが同じ
queryKey(['users']) を使用しています。 -
HeaderコンポーネントではrefetchInterval: 60000を設定し、1分ごとにデータを再フェッチします。 - データが更新されると、React Query は内部のキャッシュを更新します。
- このキャッシュは両方のコンポーネントで共有されているため、
UserListPageも自動的に最新のデータを受け取ります。 - 結果として、ヘッダーのユーザー数と一覧ページの内容が同時に更新されます。
メリット
- コード重複の削減: データフェッチのロジックを複数の場所に書く必要がありません。
- パフォーマンスの向上: 不要な API リクエストを避けられます。
- データの一貫性: アプリケーション全体で常に最新のデータを維持できます。
結論
React Query の共有キャッシュ機能を活用することで、少ないコードで効率的なデータ管理が可能になります。一箇所でデータを更新するだけで、関連するすべてのコンポーネントに変更が反映されるため、開発者の負担が軽減され、ユーザー体験も向上します。この方法は、大規模なアプリケーションでのデータ管理を大幅に簡素化し、保守性を高めることができます。