如何使用React Query与TypeScript来获取数据

442 阅读4分钟

这篇文章介绍了我们如何使用React Query与TypeScript来获取数据。我们还将介绍React Query带来的一些好处。

Getting Started with React Query and TypeScript

什么是React Query?

React Query是一个神奇的库,它帮助我们管理网络服务请求中涉及的数据

它并没有进行实际的请求--我们仍然使用 fetch或者像axios这样的库来完成这个任务。

React Query会在组件生命周期的适当时候调用我们提出请求的代码。它还将来自请求的数据放入状态,并为获取过程提供其他有用的状态变量。

在此基础上,React Query提供了大量的功能,如缓存和重试,但我喜欢React Query的一点是,它可以清理我们的代码。

安装React Query

为了安装React Query,我们在终端运行以下命令:

npm install react-query

这个包已经包括了TypeScript类型。所以,不需要单独安装这些。

使用React Query

React Query需要在需要获取数据的组件上面有一个QueryClientProvider :

import { QueryClient, QueryClientProvider } from "react-query";
...

const queryClient = new QueryClient();
render(
  <QueryClientProvider client={queryClient}>
    <App />
  </QueryClientProvider>,
  rootElement
);

QueryClientProvider 从 包中取一个 类的实例。react-query QueryClient

在获取数据的组件中,一个来自react-query 包的useQuery 钩子允许我们指定获取数据的函数:

import { useQuery } from "react-query";
...
export function App() {
  useQuery(
    ["character", { id: 1 }],  // query key
    getCharacter               // fetching function
  );
}

我们将一个键和我们的获取函数一起传入useQuery

在我们的例子中,键是一个元组,包含资源名称,"character" ,以及获取特定记录的参数,{ id: 1 }

取值函数是getCharacter - 我们稍后再看这个。

useQuery 有通用的参数,用于获取的数据类型和失败时的错误类型:

useQuery<Character, Error>(
  ["character", { id: 1 }],
  getCharacter
);

Error 是标准的错误对象

Character 的类型如下:

type Character = {
  name: string;
};

useQuery 返回有用的状态变量,可以去结构化:

const { status, error, data } = useQuery<Character, Error>(
  ["character", { id: 1 }],
  getCharacter
);
  • status 包含我们在获取过程中的位置( 或 或 或 )。"idle" "error" "loading" "success"
  • error 包含一个错误对象,如果获取错误的话。
  • data 包含已经成功获取的数据。

取值函数

获取函数的实现如下:

type Params = {
  queryKey: [string, { id: number }];
};
async function getCharacter(params: Params) {
  const [, { id }] = params.queryKey;
  const response = await fetch(`https://swapi.dev/api/people/${id}/`);
  if (!response.ok) {
    throw new Error("Problem fetching data");
  }
  const character = await response.json();
  assertIsCharacter(character);

  return character;
}

该函数接收查询键。在这个例子中,这是资源名称和参数,以获得一个特定的记录。

我们使用fetch 进行请求,如果响应不成功则抛出一个错误。React Query为我们管理这个错误,将status 状态设置为"error" ,将error 设置为Error 对象提出。

获取函数被期望从请求中返回我们想在组件中使用的数据。我们使用一个叫做assertIsCharacter类型断言函数来确保数据的类型正确:

function assertIsCharacter(character: any): asserts character is Character {
  if (!("name" in character)) {
    throw new Error("Not character");
  }
}

完成组件

下面是组件实现的其余部分:

export function App() {
  const { status, error, data } = useQuery<Character, Error>(
    ["character", { id: 1 }],
    getCharacter
  );

  if (status === "loading") {
    return <div>...</div>;
  }
  if (status === "error") {
    return <div>{error!.message}</div>;
  }
  return data ? <h3>{data.name}</h3> : null;
}

我们使用status 状态,在获取过程中显示一个加载指示器。我们还使用status ,在出现错误时显示错误信息。

当数据被返回后,我们在一个h3 元素中显示其name 属性。

React查询的好处

请注意,我们不必使用useEffect ,也不必解决其async/await问题。我们不必把响应数据放在状态中,也不必处理组件在请求过程中被卸载的情况。React查询为我们处理了这些东西,让我们简化了代码。 😊

当应用程序重新获得焦点时,React query也会自动重新获取数据,这很好。当然,这可以被禁用,但我认为这是很好的默认行为。

React query的另一个特点是,如果出现错误,它会自动重试一个获取函数,最多3次。这也是很好的默认行为,特别是如果应用程序运行在一个连接不稳定的设备上。

这篇文章中的代码可以在CodeSandbox中找到,网址是codesandbox.io/s/react-que…