⚫ React Hooks 精进 9 - 异步处理:向服务端发送请求


实现自己的 API Client

在项目内实现异步请求时第一个事情就是创建自己的 API Client,之后所有的请求都可以通过这个 Client 发出去。

  • 一些通用的 header
  • 服务器地址的配置:比如可以根据当前环境判断连接的服务器地址
  • 请求未认证的处理

使用 Hooks 思考异步请求:封装远程资源

对于一个 get 类型的 API,可以将它看成一个远程的数据源:

  • Data
  • Error
  • Pending

比起将请求直接写在组件内部,迁移到一个 Hook 内可以把组件的表现层逻辑写得更加简洁,将 API 的调用看作一个数据获取。

之后只需要将获取到的数据映射到 JSX 并显示出来即可。

这个模式仅适用于 get 请求逻辑,对于其他类型可查看第六节的 useAsync。

多个 API 调用:处理并发或者串行请求

比如一个博客文章展示页面的场景,这里需要三个请求:

  • 文章详情
  • 作者信息,包括名字,头像等
  • 文章的评论

此时包含了并发和串行的场景,文章详情和评论可以并发请求,作者的信息需要等文章内容返回才能知道作者 ID,这是串行场景。

// 传统场景
const [article, comments] = await Promise.all([
	fetchArticle(id)
	fetchComments(id)
])
const user = await fetchUser(article.user_id)

React 函数组件是一个同步函数,没有办法直接使用 await 这样的同步方法,而是需要将请求通过副作用去触发。

此时需要回到 React 的本质——状态驱动 UI。

可以从状态变化的角度去组织异步调用,通过不同的状态组合来实现异步请求的逻辑。

此时的实现思路:

  • 组件首次渲染,需要两个副作用去获取文章和评论
  • 组件首次渲染,作者 ID 不存在不发送任何请求
  • 文章内容返回,开始发送请求作者信息
  • 展示作者信息
const { data: article, loading, error } = useArticle(id);
const { data: comments } = useComments(id);
const { data: user } = useUser(article?.user_id);
// 在useUser内增加一个user_id的依赖项和判断

思考

  1. 每次调用 useArticle 这个 Hook 就会触发副作用去获取数据,但是有时候需要组件自动获取,有些需要点击某个按钮才去获取,此时如何去设计这个 Hook?

    我的回答:增加一个是否请求的 deps?

  2. Hook 都是使用 useState 保存了状态数据,意味着状态的范围限定在组件内部,组件销毁后数据就没了,此时希望数据直接缓存到全部状态该如何做?

    我的回答:使用 redux 或者 localStorage?


文章作者: 阿汪同学
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 阿汪同学 !
评论
  目录