跳到主要内容

useFetch()

当 Endpoint 不在缓存中或已过时时获取它。返回一个可与 React.use() 配合使用的 thenable——use(useFetch(endpoint, args)) 的行为与 useSuspense() 相同:数据加载时挂起,数据可用时返回反规范化数据,并在失效时重新挂起。

用法​

并行加载数据​

由于 useFetch() 和 use() 是分开调用的,多个获取会并行开始——即使第一个 use() 挂起也是如此。请参阅下方的并行获取示例。

import { use } from 'react';
import { useFetch } from '@data-client/react';
import { PostResource, CommentResource } from './Resources';

function PostWithComments({ id }: { id: number }) {
  // Both fetches start in parallel
  const postPromise = useFetch(PostResource.get, { id });
  const commentsPromise = useFetch(CommentResource.getList, {
    postId: id,
  });

  // use() reads the results — if the first suspends,
  // the second fetch is already in-flight
  const post = use(postPromise);
  const comments = use(commentsPromise);

  return (
    <article>
      <h3>{post.title}</h3>
      <p>{post.body}</p>
      <h4>Comments</h4>
      {comments.map(comment => (
        <div key={comment.id} className="listItem">
          <strong>{comment.author}</strong>: {comment.text}
        </div>
      ))}
    </article>
  );
}
render(<PostWithComments id={1} />);
结果
Store▶

预取​

useFetch() 也可以单独使用,在渲染树的较早位置确保资源在需要之前就已可用。

提示

在另一个组件中与数据绑定 hook(useCache()、useSuspense()、useDLE()、useLive())结合使用。

import { useFetch } from '@data-client/react';
import { PostResource } from './resources/Post';

function MasterPost({ id }: { id: number }) {
useFetch(PostResource.get, { id });
// ...
}

行为​

过期状态获取use() 行为resolved条件
Invalid是1挂起false不在 store 中、删除、失效
Stale是1挂起false(首次渲染、参数变化)且 过期时间 < 当前时间
Valid否返回数据true获取完成
Error否抛出错误true获取失败,由 Error Boundary 捕获
否undefined第二个参数为 null

当 store 更新时(例如通过变更或 Controller.set()),组件会重新渲染,useFetch() 会自动返回更新后的反规范化数据。

备注
  1. 相同的获取会自动去重
React Native

使用 React Navigation 时,如果数据被视为过时,useFetch() 会在获得焦点时触发获取。

条件依赖

将 null 作为任意 Data Client hook 的第二个参数,表示“什么都不做”。

// todo could be undefined if id is undefined
const todo = useFetch(TodoResource.get, id ? { id } : null);

类型​

function useFetch(
endpoint: ReadEndpoint,
...args: Parameters<typeof endpoint> | [null]
): (PromiseLike<any> & { resolved: boolean }) | undefined;

示例​

检查获取状态​

使用 promise.resolved 检查数据是否仍在加载:

import { useFetch } from '@data-client/react';
import { PostResource } from './resources/Post';

function MasterPost({ id }: { id: number }) {
const promise = useFetch(PostResource.get, { id });
if (!promise.resolved) {
// fetch is in-flight
}
// ...
}

NextJS 预加载​

为了避免 NextJS 中的获取瀑布,有时你可能需要为顶层路由添加预加载。

更多演示