如何在react-router加载器中使用React Query而不会遇到useContext错误,同时可以访问isLoading和isError状态?

问题描述 投票:0回答:1

我正在开发一个 React 应用程序,其中使用 React-router 进行路由,使用 React-query 进行数据管理。我的目标是在react-router加载器函数中获取数据,但是我在从react-query访问isLoading和isError状态时遇到了问题。

API查询及Hook定义:

import { useQuery, UseQueryResult } from '@tanstack/react-query'
import { getDefaultValues } from './apiClient'
import { AxiosError } from 'axios'

export const useFetchDefaultValues = () => {
  return useQuery({
    queryKey: ['defaultValues'],
    queryFn: () => getDefaultValues(),
  })
}

export const getDefaultValues = async () => {
  try {
    const { data } = await axios.get(`${baseUrl}/pulse/getDefaultValues`)
    return data
  } catch (error) {
    console.log(error)
    throw new Error('Error fetching default values')
  }
}

React 路由器加载器功能:

export const loader: LoaderFunction = async () => {
  const { data: defaultData } = await useFetchDefaultValues()
  return defaultData ? defaultData.results : []
}

import BreadCrumb from '@/components/BreadCrumb'
import DataTable from '@/components/DataGrid/DataTable'
import { fetchFulfilled } from '@/features/defaultValues/defaultValuesSlice'
import { useEffect } from 'react'
import { useAppDispatch } from '@/Hooks/hooks'
import { useLoaderData } from 'react-router-dom'

const ProgramOverviewPage = () => {
  const defaultData = useLoaderData() as Parameter[]
  const dispatch = useAppDispatch()

  useEffect(() => {
    if (defaultData) {
      dispatch(fetchFulfilled(defaultData))
    }
  }, [defaultData, dispatch])

  return (
    <div className='flex flex-col gap-4 h-full'>
      <div className=''>
        <BreadCrumb page='T_Program_Overview' />
      </div>
      <div className='flex-1 p-6 overflow-hidden bg-background rounded-xl'>
        <DataTable />
      </div>
    </div>
  )
}

export default ProgramOverviewPage

问题:

当尝试在加载器内使用 useFetchDefaultValues 挂钩时,我收到以下错误:

Unexpected Application Error!
Cannot read properties of null (reading 'useContext')
TypeError: Cannot read properties of null (reading 'useContext')
    at Object.useContext (http://.../react-query.js:1062:29)
    ...

在加载器中使用react-query钩子似乎不起作用,因为加载器在与React组件不同的上下文中运行。

在加载器中直接获取 API(可以工作,但缺少加载/错误状态处理):

import { defer, LoaderFunction } from 'react-router-dom'
import { getDefaultValues } from '@/api/apiClient'

export const loader: LoaderFunction = async () => {
  const defaultDataPromise = getDefaultValues()
  return defer({ defaultData: defaultDataPromise })
}

问题:当直接在加载器中获取 API 时,我成功获取了数据,但我无法访问 isLoading、isError 或其他 React Query 挂钩属性来有效管理 UI 状态。

问题:

如何在react-router加载器中正确使用react-query,同时避免useContext错误? 在加载器函数中执行 API 查询时,是否有推荐的方法来处理加载和错误状态? 如果在加载器中使用react-query不可行,那么在加载器中直接获取数据时如何有效处理加载和错误状态? 预先感谢您的帮助!

reactjs react-hooks react-router react-query tanstackreact-query
1个回答
0
投票

您无法访问 React Components 之外的钩子或自定义钩子。这些是 React 的 hooks 规则。钩子也不是异步的,所以你不能简单地

await
一个钩子。

我有一篇博客文章,用于将react-router与react-query集成,你想要做的是访问

queryClient
并在那里调用
ensureQueryData

export const loader =
  (queryClient) =>
  async () => {
    return queryClient.ensureQueryData({
      queryKey: ['defaultValues'],
      queryFn: () => getDefaultValues(),
    })
  }
© www.soinside.com 2019 - 2024. All rights reserved.