QueryClientProviderの設定エラーと解決策
React Queryを使用している際に「Error: No QueryClient set, use QueryClientProvider to set one」というエラーが発生する場合の原因と解決方法について詳しく説明します。
問題の概要
このエラーは、React Queryのフック(useQuery
など)を使用しているコンポーネントが、QueryClientProvider
でラップされていない場合に発生します。QueryClientProvider
はReact Queryのコンテキストを提供するために必要不可欠なコンポーネントです。
基本的な解決策
1. QueryClientProviderでアプリケーションをラップする
最も基本的な解決方法は、アプリケーション全体をQueryClientProvider
でラップすることです。
import React from 'react'
import ReactDOM from 'react-dom'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import App from './App'
const queryClient = new QueryClient()
ReactDOM.render(
<QueryClientProvider client={queryClient}>
<App />
</QueryClientProvider>,
document.getElementById('root')
)
TIP
React Query v3以前ではreact-query
から、v4以降では@tanstack/react-query
からインポートします。バージョンに応じた正しいインポートを使用してください。
2. コンポーネント単位でラップする方法
アプリケーション全体ではなく、特定のコンポーネントのみをラップする場合は、高階コンポーネントパターンを使用します。
import React from 'react'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
const queryClient = new QueryClient()
const withQueryProvider = (WrappedComponent) => {
return (props) => (
<QueryClientProvider client={queryClient}>
<WrappedComponent {...props} />
</QueryClientProvider>
)
}
// 使用例
const MyComponent = () => {
const { data } = useQuery({ queryKey: ['key'], queryFn: fetchData })
return <div>{data}</div>
}
export default withQueryProvider(MyComponent)
よくある問題と解決策
1. インポートの不一致
React Queryのバージョンによってインポート元が異なります:
// React Query v3以前
import { useQuery } from 'react-query'
// React Query v4以降
import { useQuery } from '@tanstack/react-query'
WARNING
プロジェクト内でインポート元が混在しているとこのエラーが発生することがあります。すべてのインポートを統一してください。
2. プロバイダーの順序問題
他のプロバイダー(ModalContextProviderなど)とQueryClientProviderの順序が正しくない場合にもエラーが発生します。
// ❌ 間違った順序
<ModalContextProvider>
<QueryClientProvider client={queryClient}>
<App />
</QueryClientProvider>
</ModalContextProvider>
// ✅ 正しい順序
<QueryClientProvider client={queryClient}>
<ModalContextProvider>
<App />
</ModalContextProvider>
</QueryClientProvider>
3. コンテキスト共有の設定
マイクロフロントエンドや複数のバンドルを使用している場合、contextSharing
プロパティを設定する必要があります。
<QueryClientProvider client={queryClient} contextSharing={true}>
<App />
</QueryClientProvider>
4. 重複したパッケージのチェック
package.json
でreact-query
と@tanstack/react-query
の両方がインストールされていないか確認し、不要な方を削除します。
# 重複パッケージの確認
npm list react-query
npm list @tanstack/react-query
# 不要なパッケージの削除
npm uninstall react-query
実践的な設定例
QueryClientProviderを別ファイルに分離
アプリケーションのメインファイルを整理するために、QueryClientProviderを別ファイルに分割する方法:
// src/providers/ReactQueryProvider.jsx
import React from 'react'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
const queryClient = new QueryClient()
const ReactQueryProvider = ({ children }) => {
return (
<QueryClientProvider client={queryClient}>
{children}
</QueryClientProvider>
)
}
export default ReactQueryProvider
// App.jsx
import React from 'react'
import ReactQueryProvider from './providers/ReactQueryProvider'
import AppRouter from './AppRouter'
const App = () => {
return (
<ReactQueryProvider>
<AppRouter />
</ReactQueryProvider>
)
}
export default App
開発者ツールのインポート
React Queryの開発者ツールもバージョンに応じて正しくインポートする必要があります:
// v3の場合
import { ReactQueryDevtools } from 'react-query/devtools'
// v4以降の場合
import { ReactQueryDevtools } from '@tanstack/react-query-devtools'
トラブルシューティング
問題が解決しない場合は、以下の点を確認してください:
- パッケージのバージョン一貫性: すべてのReact Query関連パッケージのバージョンが一致しているか
- インポートの統一: すべてのインポートが同じソースからのものか
- プロバイダーの順序: QueryClientProviderが他のプロバイダーより外側にあるか
- コンポーネントの配置: useQueryを使用するコンポーネントがQueryClientProvider内にあるか
まとめ
「No QueryClient set」エラーは、React Queryのコンテキストが正しく設定されていない場合に発生します。基本的にはアプリケーションをQueryClientProvider
でラップすることで解決しますが、バージョンの違いやプロバイダーの順序、インポートの不一致などにも注意が必要です。本記事で紹介した解決策を参考に、問題の解決に役立ててください。