翻译 | React AJAX最佳实践

前端之家收集整理的这篇文章主要介绍了翻译 | React AJAX最佳实践前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

作者:Oral (沪江Web前端开发工程师)
本文原创翻译,有不当的地方欢迎指出。转载请指明出处。

当你问起有关AJAX与React时,老司机们首先就会告诉你:React其实是个没有网络请求/AJAX功能的view库。这种说法很容易理解,但对于当你仅想让你的React组件从服务器上获取数据时,是没啥帮助的。

事实上,有很多种方法可以满足你的需求。也许你自己也脑洞大开考虑过几个,但一旦走错了方向,那代码可就一团糟了。

好吧,这下你好奇了:到底什么才是正确的、值得首选的方法呢?
答案是……看情况~~~

下面为大家一一介绍我收集的在React里使用AJAX的四个好方法。不过要注意的是,得根据app的大小及复杂度,和你已使用的库和技术来决定该使用哪种方法

1. 根组件(Root Component)方法

这是一种最简单的方法,因此它适用于简单或小型的应用。

通过这种方法,你可以建立单一根组件(父层组件)去分发所有AJAX请求,然后它会把AJAX响应数据存储进state里,以props方式传递到子组件。可以参考下官方教程上的实例。

官方教程上的实例
https://facebook.github.io/re...

此实例中的CommentBox组件就是个分发所有AJAX请求的根组件。

不过,我不大喜欢官方教程实例中的一点:它使用了jQuery去发送AJAX请求。
jQuery是个有很多功能的大库,因此仅因AJAX而引入它是没多大意义的。

我推荐使用fetch()这个简单、标准化的JavaScript 网络请求API,它已被Chrome、Firefox浏览器支持,并且可以通过使用fetch polyfill去兼容其他浏览器。如果想要更具体地了解,大家可以参考我的《AJAX库之对比》,也许这对你选择自己的AJAX库有点帮助。

AJAX库之对比
http://andrewhfarmer.com/ajax...

注意:如果你的项目有着很深的组件树结构(子组件层层嵌套下去),那么就会需要把数据从根组件一层一层传递至子组件,而这个传递数据之路将比较长。

适宜使用root component 方法的场景:

1、项目组件树比较简单
2、项目中没有使用Redux或flux

2. 容器组件方法(Container Components)

容器组件就是“为展示组件或其它容器组件提供数据和方法的组件”,如果你还没有听过这个概念,建议你可以先阅读下Dan Abramov的有关展示组件和容器组件的文章

展示组件和容器组件
https://medium.com/@dan_abram...

容器组件方法与根组件方法很像,不同的是容器组件可以支持多组件与服务器端交互。(根组件方法支持通过单一组件与服务器端交互)

容器组件方法是这样工作的:对于每个需要从服务器拿到数据的展示组件来说,需要有个可以发送网络请求的容器组件来把请求到的数据通过props传递给子组件。

举个具体的栗子:你想要展示一个有着name和picture的用户简介。我们该怎么去做呢?接下来,我们一步步来:

1.建立一个展示组件:<UserProfile />,这个组件可以接收到name 和profileImage 数据。但是这个组件一定不能有任何AJAX请求代码。 2.建立组件<UserProfileContainer />,这个组件用来接收urserId .它请求到用户的数据以后通过props传递给刚才创建的组件<UserProfile />。

这样用户简介展示就实现了。容器组件中的AJAX请求将会由简单的AJAX库发送出去,这里我推荐使用fetch()方法

fetch()方法
http://andrewhfarmer.com/ajax...

适宜为网络请求使用容器组件方法的场景:

1.项目组件树比较深
2.项目中除了某些组件需要从服务器上获取数据,绝大多数组件是不需要的。
3.项目需要从多端或多个API中获取数据。
4.项目中没有使用Redux或flux. 或者与’异步操作’方法相比,你更喜欢使用容器组件方法来完成请求数据功能

3.Redux Async Actions

Redux管理数据,而AJAX提供服务器上的数据,因此Redux 应用于处理网络请求。

如果使用Redux,就不要把AJAX放进React组件里面,而是要放进Async Actions里。

Async Actions
http://redux.js.org/docs/adva...

这里我还是推荐fetch()方法去处理实际网络请求,幸运地,Redux官方文档上也是使用fetch().文档中已有一个使用Redux、React和fetch()方法的实例

example reddit API.
http://redux.js.org/docs/adva...

如果你使用flux,那这个方法也是类似的——在actions中发送网络请求。

适宜使用Redux Async Actions的场景:

1.项目中正使用着Redux
2.项目中正使用着flux,使用方式也是类似的

4. Relay

通过Relay,你需要使用GraphQL声明React组件需要的数据,然后,Relay会自动下载数据并传递至组件的props中。

Relay
http://facebook.github.io/relay/

Relay很适用于一个大型应用中,但是对于使用者来说,还是需要比较丰富的前期知识储备的。你需要:

1.学习Relay和GraphQL.
2.使用GraphQL指定React组件的数据需求,而不是使用propTypes来指定
3.准备一台GraphQL服务器

Relay仅意味着要连接GraphQL服务器,因此它不会帮你连接任何第三方API.
目前,Relay仅能连接单一GraphQL服务器,因此,如果你要从多台服务器中获取数据,那Relay方法就不适用了。不过,将来有可能支持连接多台服务器,这个问题已经在github上讨论得热火朝天了。

github上讨论
https://github.com/facebook/r...

如果你要继续研究Relay方法,那Realy Playground 是个搞清楚它如何工作的好地方。

Realy Playground
https://facebook.github.io/re...

适宜使用Relay方法的场景:

1.想要创建一个大型应用而又比较关心Relay设计去解决的问题(https://facebook.github.io/react/blog/2015/05/01/graphql-introduction.html#why-invent-something-new)
2.项目中还没有建立JSON API
3.为项目准备一台GraphQL服务器
4.项目只会连接单一服务器

彩蛋:反模式

如果以上方法都是正确的,那么什么方法错误的呢?下面我来介绍两种大家尽量要避免使用的方法

反模式 1:在展示组件中使用AJAX请求

已经用作负责其他功能(如复杂界面渲染)的组件中就不要添加AJAX逻辑了,否则只会违反关注点分离的设计原则。

关注点分离
https://en.wikipedia.org/wiki...

反模式2:ReactDOM.render()

你可以使用完全游离于React之外的AJAX逻辑,当数据无论何时更新时,调用ReactDOM.render()来更新页面

ReactDOM.render()
https://facebook.github.io/re...

这个方法也许可以正常运行。将它以反模式方式提出来,是因为我坚信第一种根组件方法虽与其类似,但简洁多了。

结论:

使用React建立的应用都是模块化的,React会成为其中一个模块,AJAX库是另一个模块。而使用Rails和Angular框架的应用,Rails或Angular则不会成为应用中的模块。

原文:http://andrewhfarmer.com/reac...

iKcamp原创新书《移动Web前端高效开发实战》已在亚马逊、京东、当当开售。

猜你在找的React相关文章