React-query 系列第 3 部分:使用 useQuery 钩子获取数据。

2025-06-07

React-query 系列第 3 部分:使用 useQuery 钩子获取数据。

文章封面图片由Lawrence Eagles提供: React Query 3 中的新功能

大家好👋

我又回来了。我一直很感激大家的鼓励。谢谢你们💖,谢谢你们抽出时间阅读这系列冗长的第二部分:QueryClient 配置。致我的新粉丝们:谢谢你们!我会尽力不让你们失望。

react-query在第二部分中,我们讨论了如何通过为queries和设置自定义默认值来覆盖 的一些默认设置。我们为mutations等选项设置了retrystaleTimecacheTime以及refecthOnMount其他一些自定义默认值queriesretrymutations

目录

简介

在本部分中,我们将学习如何使用钩子从 API 获取数据useQuery。我之前承诺过会向您展示如何覆盖之前设置的默认值,所以我们也会讲解一下。请务必使用上面的目录跳转到与您相关的部分。

useQuery 钩子

我们首先安装axios并进行一些重构。

npm i axios
Enter fullscreen mode Exit fullscreen mode

我们QueryClient转到一个新文件./src/util/queryClient.js

import { QueryClient} from 'react-query';

const queryClientConfig = {
    defaultOptions: {
      queries: {
        retry: 2,
        staleTime: 1000 * 30,// 30 seconds
        cacheTime: 1000 * 30, //30 seconds
        refetchOnMount: "always",
        refetchOnWindowFocus: "always",
        refetchOnReconnect: "always",
        refetchInterval: 1000 * 30, //30 seconds
        refetchIntervalInBackground: false,
        suspense: false,

      },
      mutations: {
        retry: 2,
      },
    },

 export const queryClient = new QueryClient(queryClientConfig);

Enter fullscreen mode Exit fullscreen mode

如果你刚到这里,我们在这里解释了这个片段

我们App.js因此清洁我们的

import { QueryClientProvider } from 'react-query';
import { ReactQueryDevtools } from 'react-query/devtools';
import { queryClient } from "./util/queryClient";


 function App() {
   return  (
           <QueryClientProvider client={queryClient}>
             {/* The rest of your application */}
             <ReactQueryDevtools initialIsOpen={false} />
           </QueryClientProvider>
        )
 }
Enter fullscreen mode Exit fullscreen mode

我们还将创建一个queryKeys.js文件./src/util/queryKeys.js
此文件将托管我们应用程序的所有查询键。

export const fetchPostsKey = "FETCH_POSTS";
Enter fullscreen mode Exit fullscreen mode

创建一个fetchPosts.service.js文件,./src/services/fetchPosts.service.js并创建一个简单的异步函数来获取帖子列表。
我们将在本演示中使用JSONPlaceholder REST API。

import axios from "axios";

/**
 * @desc fetch a list of posts
 */
export const fetchPosts = async () => {
  const res = await axios.get(`https://jsonplaceholder.typicode.com/posts`);
  return res?.data;
};
Enter fullscreen mode Exit fullscreen mode

获取数据

Posts.js在以下位置创建组件./src/components/Posts.js

记得将你的Posts.js组件导入到你的App.js

...

 function App() {
   return  (
            <QueryClientProvider client={queryClient}>
              <Posts/>
              <ReactQueryDevtools initialIsOpen={false} />
            </QueryClientProvider>
        )
 }
Enter fullscreen mode Exit fullscreen mode

Posts.js

import { useQuery } from "react-query";
import { fetchPosts } from "../../services/fetchPosts.service";
import { fetchPostsKey } from "../../util/queryKeys";

const Posts = () => {

  const {  isLoading, isError, isSuccess, refetch, remove, data, error} = useQuery(fetchPostsKey, fetchPosts);


  return (
    <div>
      {isLoading ? (
        <div>Loading...</div>
      ) : isError ? (
        <div>An error while fetching posts</div>
      ) : (
        data?.map((post) => (
          <div key={post?.id}>
            <div>{post?.title}</div>
            <div>{post?.body}</div>
          </div>
        ))
      )}
    </div>
  );
};
export default Posts;
Enter fullscreen mode Exit fullscreen mode

useQuery钩子接受查询键作为其第一个参数,并接受查询函数作为其第二个参数。查询键是必需的,查询函数也是必需的,因为in 中
没有定义默认查询函数。让我们快速浏览一下解构对象返回的内容。queriesQueryClientuseQuery

isLoading当查询没有数据且当前正在获取数据时boolean返回的值,当没有数据时返回的值。truefalse

isError:也是一个值。当查询尝试导致错误时boolean返回。true

isSuccesstrue如果查询已收到无错误的响应并准备显示其数据,则返回。isSuccessfalse查询尚未解决或导致错误时。

refetch:这是一个手动重新获取查询的函数。

remove:此功能用于手动从缓存中删除查询。

data:这是上次成功查询的响应。如果第一次查询失败,data则会返回。undefined

error:这是查询的错误响应。当您的查询处于某种isError状态时,它会被定义。

这个useQuery钩子在解构对象中返回的值比这里描述的要多,但为了便于本文讨论,我选择了这几个。您可以在这里useQuery阅读有关这个​​钩子的更多信息

将变量传递给查询函数

那么,如果你想将一个或多个变量传递给查询函数,该怎么办呢?例如,你有一个函数,它只获取一篇帖子,并且要求你传入一个帖子id;你该怎么做呢?
让我们看看怎么做。

queryKeys.js我们将在 的文件中输入一个新的密钥./src/util/queryKeys.js

...
export const fetchSinglePostKey = "FETCH_SINGLE_POST";
Enter fullscreen mode Exit fullscreen mode

还在 创建一个fetchSinglePost.service.js文件./src/services/fetchSinglePost.service.js并创建简单的异步函数来通过 获取单个帖子id

fetchSinglePost.service.js

import axios from "axios";

/**
 * @desc fetches a single post
 */
export const fetchSinglePost = async ({queryKey}) => {
const [_key, id] = queryKey
const res = await axios.get(`https://jsonplaceholder.typicode.com/posts/${id}`);
  return res?.data;
};
Enter fullscreen mode Exit fullscreen mode

Post.js

import { useQuery } from "react-query";
import { fetchSinglePost } from "../../services/fetchSinglePost .service";
import { fetchSinglePostKey } from "../../util/queryKeys";

const Post = () => {

// fetching the post with the id of 1

  const {  isLoading, isError, isSuccess, refetch, remove, data, error} = useQuery([fetchSinglePostKey, 1], fetchSinglePost );


  return (
    <div>
      {isLoading ? (
        <div>Loading...</div>
      ) : isError ? (
        <div>An error while fetching post</div>
      ) : (
          <div >
            <div>{data?.title}</div>
            <div>{data?.body}</div>
          </div>
        )
      )}
    </div>
  );
};
export default Post;
Enter fullscreen mode Exit fullscreen mode

在这里,我们不再使用string值作为查询键,而是使用,首先传递查询字符串,然后根据查询函数的要求传递array帖子idfetchSinglePost.service.js

fetchSinglePosthook中声明的函数useQuery传入一个上下文,该上下文queryKey array嵌套在 hook 中。该queryKey数组包含查询字符串(作为数组的第一项)以及id用于获取单篇文章的变量。

记得将你的Post.js组件导入到你的App.js

...

 function App() {
   return  (
            <QueryClientProvider client={queryClient}>
               ...
              <Post/>
              <ReactQueryDevtools initialIsOpen={false} />
            </QueryClientProvider>
        )
 }
Enter fullscreen mode Exit fullscreen mode

覆盖查询默认值

我们已经看到了两个使用示例,useQuery但别忘了,它们都是在queries我们之前设置的默认值下运行的。为了覆盖某些全局配置,我们将一个对象作为第三个参数传递给useQuery钩子。每个声明了新值的选项,只会在该useQuery实例中被覆盖。

...
 const {  isLoading, isError, isSuccess, refetch, remove, data, error} = useQuery([fetchSinglePostKey, 1], fetchSinglePost, {
    refetchInterval : 3* 1000 //3 seconds
});

...
Enter fullscreen mode Exit fullscreen mode

上面这段代码的含义是,尽管我们react-query全局配置为每 30 秒重新获取一次查询,但这个特定的查询将每 3 秒重新获取一次;脱离了全局配置。

结论

我们查询返回的数据会持久化到缓存中。下一部分,我们将讨论如何与缓存交互。
感谢大家的支持。如果您是初学者,还没有写过东西,那就赶紧写吧!如果这篇文章或其中一部分对您有帮助,请给我一个💖。也欢迎评论。
在推特上关注我@NnajioforEmma10

目录

文章来源:https://dev.to/nnajiforemma10/react-query-series-part-3-data-fetching-with-the-usequery-hook-4n22
PREV
每个 UI 开发者都应该知道的 10 个 React 单行代码
NEXT
React-query 系列第 1 部分:基本 react-query 设置