React Query 项目实用指南

React Query 是一个强大的数据同步库,使得在 React 应用中处理异步请求、缓存和更新状态变得简单高效。本文将介绍如何在 React 应用中使用 React Query 的两个主要功能:useQueryuseMutation

1. 如何使用 useQuery 进行可变参数请求

在 React 应用中,我们经常需要根据用户输入或其他状态变量来发起请求。通过 useQuery,我们可以方便地实现这种可变参数的请求。

import { useQuery } from 'react-query';
import axios from 'axios';

const fetchProjects = async (searchTerm) => {
  const { data } = await axios.get('/api/projects', { params: { searchTerm } });
  return data;
};

function Projects({ searchTerm }) {
  const { data, isLoading, error } = useQuery(['projects', searchTerm], () => fetchProjects(searchTerm), { 
    enabled: !!searchTerm // 只有 searchTerm 存在时才发起请求
  });

  if (isLoading) return '加载中...';
  if (error) return `发生错误: ${error.message}`;

  return (
    <ul>
      {data.map(project => (
        <li key={project.id}>{project.name}</li>
      ))}
    </ul>
  );
}

在上面的代码中,我们使用 searchTerm 作为第二个参数传递给 useQueryqueryKey。React Query 会自动监测 searchTerm 的变化,当它改变时,重新执行 fetchProjects 函数发起新的请求。

2. useMutation 介绍和用法

useMutation 是 React Query 中用于执行造成数据变化的异步逻辑(如增加、删除、更新数据等)的 Hook。它可以帮助你管理异步逻辑的状态,并提供了取消、失败重试等功能。

import { useMutation } from 'react-query';
import axios from 'axios';

const addProject = async (newProject) => {
  const { data } = await axios.post('/api/projects', newProject);
  return data;
};

function AddProjectForm() {
  const { mutate, isLoading, error } = useMutation(addProject, {
    onSuccess: (data) => {
      console.log('项目添加成功', data);
      // ... 可能需要更新 UI 或缓存
    }
  });

  const handleSubmit = (event) => {
    event.preventDefault();
    const newProject = { name: '新项目' };
    mutate(newProject);
  };

  return (
    <form onSubmit={handleSubmit}>
      <button type="submit" disabled={isLoading}>
        {isLoading ? '提交中...' : '添加项目'}
      </button>
      {error && <p>发生错误: {error.message}</p >}
    </form>
  );
}

在这个示例中,我们创建了一个表单来添加新项目。当表单提交时,我们使用 mutate 来调用 addProject 函数执行异步请求。useMutation 提供的 onSuccessonError 回调让我们可以在请求成功或失败时执行相应的逻辑。

3. 请求参数变化时重新发起请求

当使用 useQuery 进行请求时,如果你想要在请求参数发生变化后重新发起请求,可以将参数作为 queryKey 的一部分,并确保当参数更新时组件能够重新渲染。

const { data } = useQuery(['project', projectId], () => fetchProject(projectId), {
  enabled: projectId !== null
});

这里的 projectId 是一个动态的参数,当 projectId 更新时,React Query 将自动重新加载数据。

4. 使用 react-query 完成指定次数的重试和设置超时取消自动更新

React Query 允许你设置失败重试的次数,以及请求超时时间。

const { data } = useQuery('projects', fetchProjects, {
  retry: 3, // 指定重试次数
  retryDelay: (attemptIndex) => Math.min(1000 * 2 ** attemptIndex, 30000),
  staleTime: 5000, // 数据保持新鲜的时间
  cacheTime: 10000, // 缓存数据保留时间
  refetchInterval: false, // 设置为 false 取消自动重新获取
  refetchOnWindowFocus: false // 取消窗口聚焦时的自动重新获取
});

在这个配置中,我们设置了最多重试三次,重试间隔为指数增长策略,数据在 5 秒内视为最新(staleTime),同时保持缓存时间为 10 秒,而 refetchIntervalrefetchOnWindowFocus 配置为 false 可以阻止自动的更新行为。

至此,你已经了解了如何在 React 应用中使用 React Query 的基本功能。这些功能有效地简化了数据获取和数据突变的过程,并且提供了强大的缓存和更新机制。在实际项目中,合理地使用 React Query 可以在很大程度上提高开发效率和用户体验。


English version

Practical Guide to React Query

React Query is a powerful data synchronization library that simplifies the process of handling asynchronous requests, caching, and updating state in React applications. This article will introduce how to use two main features of React Query in React applications: useQuery and useMutation.

1. How to Use useQuery for Variable Parameter Requests

In React applications, we often need to initiate requests based on user input or other state variables. Through useQuery, we can easily implement requests with variable parameters.

import { useQuery } from 'react-query';
import axios from 'axios';

const fetchProjects = async (searchTerm) => {
  const { data } = await axios.get('/api/projects', { params: { searchTerm } });
  return data;
};

function Projects({ searchTerm }) {
  const { data, isLoading, error } = useQuery(['projects', searchTerm], () => fetchProjects(searchTerm), { 
    enabled: !!searchTerm // Only initiate the request if searchTerm exists
  });

  if (isLoading) return 'Loading...';
  if (error) return `An error occurred: ${error.message}`;

  return (
    <ul>
      {data.map(project => (
        <li key={project.id}>{project.name}</li>
      ))}
    </ul>
  );
}

In the code above, we use searchTerm as the second argument to pass to useQuery‘s queryKey. React Query automatically monitors changes to searchTerm, and when it changes, it re-executes the fetchProjects function to initiate a new request.

2. Introduction and Usage of useMutation

useMutation is a hook in React Query used for executing asynchronous logic that causes data changes (such as adding, deleting, updating data, etc.). It helps you manage the state of asynchronous logic and offers features like cancellation and failure retry.

import { useMutation } from 'react-query';
import axios from 'axios';

const addProject = async (newProject) => {
  const { data } = await axios.post('/api/projects', newProject);
  return data;
};

function AddProjectForm() {
  const { mutate, isLoading, error } = useMutation(addProject, {
    onSuccess: (data) => {
      console.log('Project added successfully', data);
      // ... might need to update UI or cache
    }
  });

  const handleSubmit = (event) => {
    event.preventDefault();
    const newProject = { name: 'New Project' };
    mutate(newProject);
  };

  return (
    <form onSubmit={handleSubmit}>
      <button type="submit" disabled={isLoading}>
        {isLoading ? 'Submitting...' : 'Add Project'}
      </button>
      {error && <p>An error occurred: {error.message}</p >}
    </form>
  );
}

In this example, we created a form to add new projects. When the form is submitted, we use mutate to call the addProject function to execute the asynchronous request. The onSuccess and onError callbacks provided by useMutation allow us to execute the appropriate logic when the request is successful or fails.

3. Re-initiating Requests When Request Parameters Change

When using useQuery to make requests, if you want to re-initiate the request after the request parameters change, include the parameters as part of the queryKey and ensure that the component can re-render when the parameters update.

const { data } = useQuery(['project', projectId], () => fetchProject(projectId), {
  enabled: projectId !== null
});

Here, projectId is a dynamic parameter. When projectId updates, React Query will automatically reload the data.

4. Using react-query to Perform Specified Number of Retries and Set Timeout to Cancel Automatic Updates

React Query allows you to set the number of retries for failures, as well as the request timeout.

const { data } = useQuery('projects', fetchProjects, {
  retry: 3, // Specify the number of retries
  retryDelay: (attemptIndex) => Math.min(1000 * 2 ** attemptIndex, 30000),
  staleTime: 5000, // Time for data to stay fresh
  cacheTime: 10000, // Data cache retention time
  refetchInterval: false, // Set to false to cancel automatic refetch
  refetchOnWindowFocus: false // Cancel automatic refetch when window is focused
});

In this configuration, we set a maximum of three retries, with retry intervals following an exponential growth strategy, data considered fresh within 5 seconds (staleTime), while maintaining cache time for 10 seconds. Setting refetchInterval and refetchOnWindowFocus to false prevents automatic update behavior.

With this, you now understand how to use the basic features of React Query in React applications. These features effectively simplify the processes of data fetching and data mutation, and provide powerful caching and updating mechanisms. Using React Query appropriately in real projects can significantly improve development efficiency and user experience.

原文链接:https://juejin.cn/post/7321924572055552034 作者:慕仲卿

(0)
上一篇 2024年1月10日 上午10:05
下一篇 2024年1月10日 上午10:15

相关推荐

发表回复

登录后才能评论