【问题标题】:No QueryClient set, use QueryClientProvider to set one没有设置QueryClient,使用QueryClientProvider设置一个
【发布时间】:2021-01-06 04:25:40
【问题描述】:

我第一次尝试响应查询,然后在我的 React 应用程序开始时得到了这个。

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

【问题讨论】:

    标签: javascript reactjs react-query


    【解决方案1】:

    正如错误提示的那样,您需要将应用程序包装在 QueryClientProvider 中。这是docs的第一页:

    import { QueryClient, QueryClientProvider, useQuery } from 'react-query'
    
    const queryClient = new QueryClient()
    
    export default function App() {
       return (
         <QueryClientProvider client={queryClient}>
           <Example />
         </QueryClientProvider>
       )
    }
    

    【讨论】:

      【解决方案2】:

      虽然这最常见的原因是没有将您的应用程序包装在 &lt;QueryClientProvider&gt; 中,但在我的情况下,这是因为我正在导入一些共享组件,最终导致不同的上下文。您可以通过将contextSharing 选项设置为true 来解决此问题

      看起来像:

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

      来自文档:(https://react-query.tanstack.com/reference/QueryClientProvider)

      contextSharing: 布尔值(默认为 false)

      将此设置为 true 以启用上下文共享,这将跨窗口共享上下文的第一个和至少一个实例,以确保如果跨不同的包或微前端使用 React Query,它们都将使用相同的上下文实例,无论模块范围如何。

      【讨论】:

        【解决方案3】:
        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>
        );
            
        }
        

        【讨论】:

        • 感谢这位朋友。 Wrapped 类型对我来说是缺失的部分。
        【解决方案4】:

        我试图解决同样的问题:

        我关注了React Query docs 并使用了Higher Order Component的概念

        看看是否有帮助:
        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);
        

        【讨论】:

        • 很棒的工作!对于useQuery ,这是一个很好的模式
        【解决方案5】:

        只需进行如下更改即可正常工作

        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')
        );
        

        【讨论】:

          【解决方案6】:

          单一 SPA(微前端)- React Query v3.34.15

          我在尝试将 sigle-spa react parcel 集成到根应用程序时遇到此错误。

          我使用craco-plugin-single-spa-application 构建了一个 CRA 应用程序,以使其适应包裹。在 entry 配置中,我指向了我的 single-spa-react 配置。

          // 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 
                }
              }
            ]
          }

          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

          在阅读了一堆论坛和 react-query 文档之后,我发现我唯一需要更改的就是将 QueryClientProvider 属性 contextSharing 传递为 true。完成此更改后,运行建筑物并访问打开我的包裹的路线。我遇到了同样的错误。

          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')
          )

          但是,我该如何解决。嗯,这很简单。我什至无法想象它为什么在本地工作。但不是在构建和集成之后。

          问题是因为我将 React Query Provider 放在了应用程序的索引中,而在我的 single-spa-index.cf.js 中,我正在导入 import App from '../App',它实际上并没有被提供程序包装。一旦我还在应用程序索引中导入 App ,它被包装在其中,使其在本地工作。 ??

          所以在弄清楚之后,我的代码是这样的: 解决后的代码

          // 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')
          )

          嗯,这很长,但我希望它可以帮助遇到与我相同问题的人。 ???

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2022-10-18
            • 2015-09-02
            • 2019-01-24
            • 2020-12-16
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多