【译】为 REST API 创建可复用的 React Query 组件

2,435 阅读4分钟

原文地址: medium.com/@TimKolb/cr…
译文地址:github.com/xiao-T/note…
本文版权归原作者所有,翻译仅用于学习。


每次实现一个新的 UI 组件时,我都是先实现布局,然后,mock 数据用于 defaultProps,并提供一个空的点击监听模拟用户交互。然后,用真实的数据替换掉 mock 的函数和 props。

为了实现那些需要从服务端获取数据数据的组件,我一次次的重复着相同的操作。使用和配置 HTTP headers,反序列化逻辑、处理成功或者失败的回调、loading 状态等等,这就导致了代码的重复。

通信逻辑让可复用的组件来处理,是不是更好呢?

💪 开始

React 应用中那些需要使用 API 的组件需要处理大量的问题。针对每个请求,你都需要处理 loading、错误和成功的状态。

把所有的功能整合到现有的组件中势必增加组件的复杂度,这并不符合 React 组件化思想。

计算机科学不再是新鲜事物,我们也发现了一些旧时代的规则和工具。其中之一就是:分离。

编写程序只做一件事情并做好 — Doug McIlroy

我们把 Unix 管道发明者的这个理念引入到 React 组件中,React 的组件代表着 Unix 系统中的程序。通过 props 控制组件的行为,实现万能的组件。JavaScript 中通用的类型就是函数 — 这就引出了复合组件

🔌 通过复合组件提供可复用的功能

复合组件模式是由 Kent C. Dodds 提出并推广的。除了一物理念之外的另外一种设计理念:控制权倒置,将非核心的功能转移到另外一个组件。

使用 Query 组件可以通过 URL 获取数据 — 这是基本功能。根据查询结果,使用者有权决定如何渲染 jsx 元素。Query 组件不会与任何组件、任何 URL 或者其它预设属性耦合。

不管在什么地方使用,它完全可以定制。你可以提供一个自定义的反序例化函数来处理不同的响应类型,比如:json、 text 或者 xml,然后,检查响应状态,并在适当的位置改变默认行为。基于响应结果,state reducer 可以让你拦截状态的更新情况来改变 Query 组件的行为。

Query 组件是一个复合组件,另外提供一个 React Context Provider 来包装子组件。这有利于复合组件的使用。我们来看看具体的操作:

img

如果,你深入了解过 GraphQL,你应该看到过由 react-apollo 提供的 Query、Mutation 和 Subscription 组件。这些组件提供了简洁明了的 API,以便在 React 组件中整合服务端的通信逻辑,甚至,使用 apollo-link-rest 可以处理 REST APIs。我非常喜欢这种良好的编码体验。但是,有些情况下,你并不希望使用这些依赖库。因此,我们可以尝试为我们的 REST API 创建类似的方案。

我们先来看看一个 Query 组件会传入哪些额外的信息以便子组件使用,比如:loading 和请求的错误状态。

⚙️ 自定义

Query 组件基本上就是一个组件,只是它提供了 fetch 的功能。React 应用中任何需要从服务器获取数据的地方都可以使用它,这样也保证了代码的可读性。

服务器通信并不是只有 GET 请求。有时,用户交互也会触发请求,以便创建、更新或者删除一个实体。

根据用户交互我们可以改变 Query 组件的行为。比如,我们可以改变每个 fetch 的选项,以便处理不同的 HTTP 方法,比如:POST、DELETE 或者改变 URL。

🛍 外卖

在组件中整合服务器通信代码会让你的代码变得混乱。把重复的请求逻辑提取到一个复合组件中,可以提高应用中代码的复用率。这种模式可以让你的代码 DRY,并利用基于组件的 React 方法和关注点的分离核心思想。

✍️ CodeSandbox 演示

Queyr Component Demo

👋 大家好!我是 Tim Kolberger。我是一名全栈 web 开发者,在德国,达姆施塔特的 Incloud 公司工作。我喜欢 React、GraphQL 和 JavaScript。