react 翻页 ajax,React的AJAX最佳实践

引言

当你开始问 AJAX 和 React 的时候,大神们告诉的你的第一件事是 React 是一个视图层的库而且 React 没有网络/AJAX 的功能特性。

了解这点虽然是应该的,但在你想要从服务器获取的数据放到 React 组件中的时候却并没有什么用。

实际上,实现这个的方式有很多。你自己说不定就有好几种想法,但是如果你选择了一种错误的方法,你的代码可能会很混乱。

所以你可能会想:哪种方式是『对的』或者『更优的』。

从服务器获取数据到 React 组件中的最佳实践是什么?

答案是…看具体情况。

四种方法

我收集了四种不错的实现 AJAX 和 React 的方法。

使用哪种方式取决于你的应用的大小和复杂度,以及你已经在使用的是哪些库和技术。

1.根组件

2.容器组件

3.Redux 异步 Action

4.Relay

React_AJAX_1_root_component.png

React_AJAX_2_container_components.png

React_AJAX_3_redux_async_actions.png

React_AJAX_4_relay.png

根组件

这种方式最简单所以很适合原型构建和小型应用。

使用这种方法的时候,你需要创建一个根/父组件来管理所有 AJAX 请求。根组件在自己的状态中保存了所有 AJAX 响应数据,并且将状态(或者状态的一部分)作为属性传递到子组件中。

React_AJAX_1_root_component.png

关于这种方式的例子可以查看React 官方教程。CommentBox 组件用于发所有 AJAX 请求。

译者注:作者写本文的时候 React 官方教程还是 Thinking in React,现在官网已经更新了新的教程,新的教程中不含 AJAX 操作,详细请查阅文末的参考 3。

官方教程中我不喜欢的一个地方是他们使用了 jQuery 来发送 AJAX 请求。jQuery 是一个拥有诸多功能特性的大型库,所以只用它做 AJAX 是毫无道理的。

我推荐使用 fetch() 函数。它是一个简单的,标准的,JavaScript AJAX API。Chrome 和 Firefox 已经支持这个函数,在 node 和其他浏览器中也可以通过 polyfill 实现。想要选择自己得 AJAX 库,或者想要了解 fetch() 的详情,请看我的文章AJAX 库的比较。

另一个坑:如果你有一个较深的组件树(子组件的子组件的子组件…),那么你将要把数据传递得很长很长,从根组件到更深的组件。

什么时候使用根组件:

你的组件树比较浅。

你没有在用 Redux 或者 flux。

容器组件

一个容器组件用于为展现组件(presentational conponents)或者其他容器组件提供数据和行为。如果你还没听过这个词,我推荐 Dan Abramov 的『展现和容器组件』。

React_AJAX_2_container_components.png

对于我们的目的来说,容器组件这种方式跟根组件方式一样,只是容器组件方式有多个组件和服务器进行交互。

工作原理如下:对于每个需要服务器数据的展现组件,创建一个发送 AJAX 请求的容器组件以获取数据,并通过属性为子组件提供数据。

举个实用的例子,假设你要用用户名和图片来展示一个用户的信息。

首先创建一个接收 name 和 profileImage 属性的UserProfile的展示组件。该组件不应该有任何 AJAX 代码。

然后创建一个接收 userId 属性的UserProfileContainer组件。它为特定的用户下载数据并通过属性传递给UserProfile。

在容器组件中的 AJAX 请求可以通过简单的 AJAX 库发送。我推荐fetch()。

什么时候使用容器组件做 AJAX:

你有一个很深的组件树。

你的部分组件需要从服务器获取数据,但大多数组件都不需要。

你在从多个 API 获取数据。

你没有在用 Redux/flux,或者你倾向于使用容器组件来做『异步动作』。

Redux 异步 Action

React_AJAX_3_redux_async_actions.png

Redux 管理数据,而 AJAX 从服务器提供数据,所以由 Redux 代码应该管理你的网络请求是有道理的。

如果你使用 Redux,那别把 AJAX 放在你的 React 组件中,而应该放到你的异步 Action中。

我推荐使用fetch()函数来处理实际网络请求,而正好,Redux 官方文档中也是用的 fetch()。官方文档中甚至用 Redux、React 和 fetch() 写了一个 reddit 示例 API。

如果你在用 flux,那跟这种方式类似,在你的 action 中发送网络请求。

什么是偶使用 Redux 异步 Actions:

如果你在使用 Redux,这就是你在找的方法。

如果你在使用 flux,你的方式应该跟这个很类似。

Relay

如果使用Relay,就要用 GraphQL 声明 React 组件的数据需求,Relay 会自动下载数据并填充到组件的属性中。

React_AJAX_4_relay.png

Relay 很适应大型应用来的场景,但是需要需要更多的准备成本。你需要:

学习 Relay 和 GraphQL。

使用 GrahpQL 指定 React 组件的数据需求(而不是 propTypes)。

设置一个 GraphQL 服务器。

Relay 只负责和 GraphQL 服务器进行通信,所以它不会和任何三方 API 进行通信。

目前 Relay 只能和单一 GraphQL 服务器通信,所以如果你在从多个数据源获取数据,这种方法就不适合。和多个数据源通信的特性应该会在后续版本中添加,相关情况在这个GitHub Issue中有讨论。

如果你打算使用这种方式,Relay Playground是一个用来搞清楚 Relay 是怎么工作的的一个好地方。

什么时候使用 Relay:

构建一个大型应用,并且正在担忧的问题正好是 Relay 被设计出来解决的相关的问题。

你还没有一个已经构建好的 JSON API。

你打算设置一个 GraphQL 服务器。

你的应用只和单台服务器进行通信。

附赠:反模式(Anti-patterns)

如果上述的所有方法都是符合需求的,那哪些不应该选择呢?我建议一般应该避免这两种方式。

反模式 1:在展现组件中的 AJAX 请求

不要在一个已经有其他功能的组件中实现 AJAX 逻辑,比如一个在做复杂接口的渲染组件。这会破坏关注分离(Separation of concerns)的设计原则。

反模式 2:ReactDOM.render()

你可能有在整个 React 逻辑外面写了 AJAX 逻辑并且在当获取了服务器的更新数据时调用ReactDOM.render()。

这种方式可能没有问题。我不建议这么做是因为我认为根组件模式跟这种做法相似,并且更简洁。

总结

使用 React 不是 Rails 或者 Angular,React 构建的应用是多模块的(Modular),React 只是其中的一个模块,AJAX 库是另一个模块。

你也许会需要了解一些其他模块,以及怎样把他们整合并适应在一起。

做 XXX 的最好的库是什么?怎样整合 YYY 和 React?我的博客会经常更新,并主要就是回答这类问题。

参考

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值