【问题标题】:React Query does not work with Astro FrameworkReact Query 不适用于 Astro 框架
【发布时间】:2023-02-01 16:05:00
【问题描述】:

我正在尝试将 React-Query 与 Astro 结合使用以从我的 Django Rest Framework 后端获取数据。 Astro 是组织我基于反应的前端的好方法,但我担心它可能与 React-Query 不兼容。

每当我尝试对我的后端进行查询时,我都会得到 true 的“isLoading”值(以及 isError 的 false)。然而,我从来没有设法从我的端点恢复数据。

我一直在关注各种具有相同结果的教程。这是我卡住的代码:

import { QueryClient, useQueryClient, QueryClientProvider, useQuery } from '@tanstack/react-query';
import { gettestApi } from "../../api/testApi";

function MyComponent(props) {
    const queryClient = useQueryClient();
    const {
        isLoading,
        isError,
        error,
        data: test
    } = useQuery('test', gettestApi)

    let content
    if (isLoading) {
        content = <p>Loading...</p>
    } else if (isError){
        content = <p>{error.message}</p>
    } else {
        content = JSON.stringify(test)
    }

如您所见,我从 /api/testAPI.js 导入了一个 axios 函数,如下所示:

import axios from "axios"

const testApi = axios.create({
    baseURL: "http://127.0.0.1:8000"
})

export const gettestApi = async () => {
    return await testApi.get("/api/endpoint/").then(response => response.data)
}

这就是我所见过的大多数教程和官方文档对示例的总结方式,但是应该由该端点触发的我的后端服务器绝对没有记录来自 react-query 的命中,这让我很好奇。我知道没有什么“调用”我的反应查询或我的 gettestApi() 函数,但其​​他人似乎没有必要检索他们的数据。

也许指出与 React 的其他框架相反,Astro 没有 App.js 根包围起来可能会很有用

<QueryClientProvider client={client}>
<App />
</QueryClientProvider>

相反,我已将这些 QueryClientProvider 括号添加到我能做到的最高级别的 React 组件中。

我觉得我缺少一些关于 Tanstack Query/React-Query 的直觉。有人能指出我正确的方向吗?非常感谢您的帮助。

【问题讨论】:

    标签: reactjs react-native react-query astrojs astro


    【解决方案1】:

    从我在astro docs 看到的:

    关于 Astro 组件最重要的一点是它们会在您构建期间呈现为 HTML。即使您在组件内部运行 JavaScript 代码,它也会提前运行,从您发送给用户的最终页面中删除。结果是一个更快的站点,默认情况下添加的 JavaScript 足迹为零。

    所以似乎所有的反应代码只在服务器上运行,通过useEffectuseSyncExternalStore订阅获取的数据不会运行。但这正是 react-query 正在做的,所以是的,我认为它们不能很好地协同工作。我也不确定在没有客户端 javascript 的情况下,设置中 react-query 的目的是什么。

    【讨论】:

      【解决方案2】:

      您可以在 Astro 组件上设置 client:only,这样 React 组件就不会在服务器上运行。存在共享状态限制,但 React Query 感觉仍然比 fetch + useEffect + 自己的代码更好,即使它不在一个完整的 React 应用程序中。在这个例子中,我还使用了一个 init 函数,它从客户端的浏览器读取 cookie,这是何时使用 client:only 的另一种情况。

      天文:

      ---
      import Layout from "../../layouts/Layout.astro";
      import ClientPanel from "../../components/client/ClientPanel";
      ---
      <Layout title={ 'Client' }>
          <ClientPanel client:only></ClientPanel>
      </Layout>
      

      反应:

      // imports
      
      const queryClient = new QueryClient()
      
      /** client:only component */
      const ClientPanel = () => (
          <QueryClientProvider client={queryClient}>
            <ClientData />
          </QueryClientProvider>
      )
      
      const ClientData = () => {
          
          const { getUser, getSession } = useSession(); // read cookies functions
          const [ user, setUser ] = useState(getUser);
      
          const { isLoading, error, data } = useQuery({
              queryKey: ['patientData'],
              queryFn: () => getSession() // validate or refresh token
              .then(session => fetchPatientData(session.tokens.token))
              .catch(error => error === 'INVALID_SESSION' ? null : undefined)
          })
      
          if (!user || data === null) window.location.replace('/login')
          
          // return statement, etc.
      

      【讨论】:

        猜你喜欢
        • 2022-12-19
        • 2018-05-04
        • 1970-01-01
        • 2021-06-07
        • 2015-11-12
        • 2011-06-16
        • 2018-01-05
        • 2020-12-10
        • 1970-01-01
        相关资源
        最近更新 更多