67

I was trying React Query and got this at the start of my React app.

screenshot of the error: "Error: No QueryClient set, use QueryClientProvider to set one"

import React from 'react'
import { useQuery } from "react-query";
    
const fetchPanets = async () => {
    const result = await fetch('https://swapi.dev/api/people')
    return result.json()
    }
    
const Planets = () => {
    const { data, status } = useQuery('Planets', fetchPanets)
    console.log("data", data, "status", status)
    return (
        <div>
            <h2>Planets</h2>
        </div>
    )
}
    
export default Planets
double-beep
  • 5,031
  • 17
  • 33
  • 41
Jamal
  • 879
  • 1
  • 10
  • 14

12 Answers12

73

As the error suggests, you need to wrap your application in a QueryClientProvider. This is on the first page of the docs:

import { QueryClient, QueryClientProvider, useQuery } from 'react-query'

const queryClient = new QueryClient()

export default function App() {
   return (
     <QueryClientProvider client={queryClient}>
       <Example />
     </QueryClientProvider>
   )
}
Ivan Bila
  • 747
  • 7
  • 9
TkDodo
  • 20,449
  • 3
  • 50
  • 65
  • 9
    I use package "react-query" first then I realize there is a newer version "@tanstack/react-query". So after a while a realize I use the provider from the newer version but consumer code was using "useMutation" from the old package. That's why it cannot not find the Provider for my old code. – Foxeye.Rinx Jan 29 '23 at 18:12
35

While this is most commonly caused by not having your application wrapped in a <QueryClientProvider>, in my case it happened because I was importing some shared components, which ended up with a different context. You can fix this by setting the contextSharing option to true

That would look like:

 import { QueryClient, QueryClientProvider } from 'react-query'
 
 const queryClient = new QueryClient()
 
 function App() {
   return <QueryClientProvider client={queryClient} contextSharing={true}>...</QueryClientProvider>
 }

From the docs: (https://react-query.tanstack.com/reference/QueryClientProvider)

contextSharing: boolean (defaults to false)

Set this to true to enable context sharing, which will share the first and at least one instance of the context across the window to ensure that if React Query is used across different bundles or microfrontends they will all use the same instance of context, regardless of module scoping.

Fred Antell
  • 541
  • 6
  • 10
13

Just make changes like below it will work fine

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import { QueryClient, QueryClientProvider } from "react-query";
const queryClient = new QueryClient();

ReactDOM.render(
  <QueryClientProvider client={queryClient}>
    <App />
  </QueryClientProvider>,
  document.getElementById('root')
);
Rocky
  • 515
  • 1
  • 7
  • 18
12

In my case I was importtng from 'react-query' in one place and '@tanstack/react-query' in another.

gx0r
  • 4,682
  • 2
  • 23
  • 24
5
import {  QueryClient, QueryClientProvider, useQuery } from 'react-query';
const queryClient = new QueryClient();
const fetchPanets = async () => {
    const result = await fetch('https://swapi.dev/api/people')
    return result.json()
}

const Planets = () => {
    const { data, status } = useQuery('Planets', fetchPanets)
    console.log("data", data, "status", status)
    return (
        <div>
            <h2>Planets</h2>
        </div>
    );
}


export default function Wraped(){
return(<QueryClientProvider client={queryClient}>
        <Planets/>
    </QueryClientProvider>
);
    
}
Community
  • 1
  • 1
3

Single SPA (micro-frontend) - React Query v3.34.15

I was getting this error while trying to integrate a sigle-spa react parcel into the root application.

I used craco-plugin-single-spa-application for the building of a CRA app as a way to adapt it for a parcel. In the entry config I was pointing to my single-spa-react config.

// craco.config.js

const singleSpaApplicationPlugin = require('craco-plugin-single-spa-application')

module.exports = {
  plugins: [
    {
      plugin: singleSpaApplicationPlugin,
      options: {
        orgName: 'uh-platform',
        projectName: 'hosting',
        entry: 'src/config/single-spa-index.cf.js',
        orgPackagesAsExternal: false,
        reactPackagesAsExternal: true,
        externals: [],
        minimize: false 
      }
    }
  ]
}

In the single-spa-index.cf.js file I had the following configs.

import React from 'react'
import ReactDOM from 'react-dom'

import singleSpaReact from 'single-spa-react'

import App from '../App'

const lifecycles = singleSpaReact({
  React,
  ReactDOM,
  rootComponent: App,
  errorBoundary() {
    return <div>Ocorreu um erro desconhecido!</div>
  }
})

export const { bootstrap, mount, unmount } = lifecycles

After reading a bunch of forums and the react-query documentation, the only thing that I figured out I needed to change was pass in the QueryClientProvider the prop contextSharing as true. After had did this change, ran the building and access the route that opens my parcel. I got the same error.

import React from 'react'
import ReactDOM from 'react-dom'
import { QueryClient, QueryClientProvider } from 'react-query'
import { ReactQueryDevtools } from 'react-query/devtools'

import App from './App'

const queryClient = new QueryClient()

const isDevelopmentEnv = process.env.NODE_ENV === 'development'

if (isDevelopmentEnv) {
  import('./config/msw/worker').then(({ worker }) => worker.start())
}

ReactDOM.render(
  <React.StrictMode>
    <QueryClientProvider contextSharing={true} client={queryClient}>
      <App />
      {isDevelopmentEnv && <ReactQueryDevtools initialIsOpen={false} />}
    </QueryClientProvider>
  </React.StrictMode>,
  document.getElementById('root')
)

But, how do I solved that. Well, it was was simple. I couldn't even imagine why it was working locally. But not after building and integration.

The problem was because I put the React Query Provider inside the index o the application and in my single-spa-index.cf.js I was importing import App from '../App' which really wasn't wrapped by the provider. Once I also was importing App in the application index, where It was wrapped making It works locally.

So after figure that out, my code was like that: CODE AFTER SOLUTION

// craco.config.js
const singleSpaApplicationPlugin = require('craco-plugin-single-spa-application')

module.exports = {
  plugins: [
    {
      plugin: singleSpaApplicationPlugin,
      options: {
        orgName: 'uh-platform',
        projectName: 'hosting',
        entry: 'src/config/single-spa-index.cf.js', 
        orgPackagesAsExternal: false,
        reactPackagesAsExternal: true,
        externals: [], 
        minimize: false 
      }
    }
  ]
}

// src/config/single-spa-index.cf.js 
import React from 'react'
import ReactDOM from 'react-dom'

import singleSpaReact from 'single-spa-react'

import App from '../App'

const lifecycles = singleSpaReact({
  React,
  ReactDOM,
  rootComponent: App,
  errorBoundary() {
    return <div>Ocorreu um erro desconhecido!</div>
  }
})

export const { bootstrap, mount, unmount } = lifecycles


// App.tsx
import { QueryClient, QueryClientProvider } from 'react-query'
import { ReactQueryDevtools } from 'react-query/devtools'

import { config } from 'config/react-query'
import Routes from 'routes'
import GlobalStyles from 'styles/global'

import * as S from './styles/shared'

const queryClient = new QueryClient(config)

const isDevelopmentEnv = process.env.NODE_ENV === 'development'

if (isDevelopmentEnv) {
  import('./config/msw/worker').then(({ worker }) => worker.start())
}

function App() {
  return (
    <QueryClientProvider contextSharing={true} client={queryClient}>
      <S.PanelWrapper>
        <Routes />
        <GlobalStyles />
      </S.PanelWrapper>

      <ReactQueryDevtools initialIsOpen={false} />
    </QueryClientProvider>
  )
}

export default App

// index.tsx
import { StrictMode } from 'react'
import ReactDOM from 'react-dom'

import App from './App'

ReactDOM.render(
  <StrictMode>
    <App />
  </StrictMode>,
  document.getElementById('root')
)

Well, it was long but I hope it helps someone that's undergoing for the same problem as mine.

niltonxp
  • 342
  • 4
  • 11
3

I got that error when trying to add the react-query devtools.

The problem was I was installing it wrongly according my version, I was using react-query v3.

WRONG FOR react-query V3 (GOOD FOR V4)

import { ReactQueryDevtools } from '@tanstack/react-query-devtools';

OK FOR react-query V3

import { ReactQueryDevtools } from 'react-query/devtools';
Juanma Menendez
  • 17,253
  • 7
  • 59
  • 56
2

I was trying to fix the same thing:

I followed the React Query docs and used the concept of Higher Order Component

See if it helps:
import React from 'react';
import { QueryClient, QueryClientProvider, useQuery } from 'react-query';

import Planet from './Planet';

const queryClient = new QueryClient();

const fetchPlanets = async () => {
    const res = await fetch('http://swapi.dev/api/planets/');
    return res.json();
}

const Planets = () => {

    const { data, status } = useQuery('planets', fetchPlanets);

    return (
        <div>
            <h2>Planets</h2>
            { status === 'loading' && (<div>Loading data...</div>)}
            { status === 'error' && (<div>Error fetching data</div>)}
            {
                status === 'success' && (
                    data.results.map(planet =>
                        <Planet
                            key={planet.name}
                            planet={planet}
                        />
                    )
                )
            }
        </div>
    )
}

// Higher order function
const hof = (WrappedComponent) => {
    // Its job is to return a react component warpping the baby component
    return (props) => (
        <QueryClientProvider client={queryClient}>
            <WrappedComponent {...props} />
        </QueryClientProvider>
    );
};

export default hof(Planets);
smallfoxy
  • 51
  • 6
2

In my case I accidentally used two different versions of react-query in my modules.

Metin Celik
  • 194
  • 2
  • 11
2

Just be careful when upgrade from react-query v3 to @tanstack/react-query v4.

Ensure that you replace all imports as "react-query" to "@tanstack/react-query" and then run yarn remove the lib that you won't use anymore, otherwise you may accidentally import the unexpected one. This happened to me and caused this error.

haptn
  • 650
  • 6
  • 11
1

In my case

Error import { QueryClient, QueryClientProvider } from "@tanstack/react-query";

Solution import { QueryClient, QueryClientProvider } from "react-query";

remove it @tanstack/

1

For me it's caused by react-query devtools

  • "react-query": "^3.39.3"
  • "react-query-devtools": "^2.6.3"

and importing like this:

  • import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
  • import { ReactQueryDevtools } from 'react-query/devtools';

So, the solution is change the version using:

  • "@tanstack/react-query": "^4.13.0",
  • "@tanstack/react-query-devtools": "^4.13.0",

and import like this:

  • import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
  • import { ReactQueryDevtools } from '@tanstack/react-query-devtools';