美文网首页前端跟我学Web前端之路
翻译 | React AJAX最佳实践

翻译 | React AJAX最佳实践

作者: iKcamp | 来源:发表于2017-01-03 13:28 被阅读375次

    作者:张捷(沪江Web前端开发工程师)

    本文原创翻译,有不当的地方欢迎指出。转载请指明出处。

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

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

    好吧,这下你好奇了:到底什么才是正确的、值得首选的方法呢?

    答案是……看情况~~~

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

    1.根组件(Root Component)方法

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

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

    官方教程上的实例

    https://facebook.github.io/react/tutorial/tutorial.html

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

    不过,我不大喜欢官方教程实例中的一点:它使用了jQuery去发送AJAX请求。

    jQuery是个有很多功能的大库,因此仅因AJAX而引入它是没多大意义的。

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

    AJAX库之对比

    http://andrewhfarmer.com/ajax-libraries

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

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

    1、项目组件树比较简单

    2、项目中没有使用Redux或flux

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

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

    展示组件和容器组件

    https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0

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

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

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

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

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

    fetch()方法

    http://andrewhfarmer.com/ajax-libraries

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

    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/advanced/AsyncActions.html

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

    example reddit API.

    http://redux.js.org/docs/advanced/ExampleRedditAPI.html

    如果你使用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/relay/issues/114

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

    Realy Playground

    https://facebook.github.io/relay/prototyping/playground.html

    适宜使用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/Separation_of_concerns

    反模式2:ReactDOM.render()

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

    ReactDOM.render()

    https://facebook.github.io/react/docs/react-api.html

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

    结论:

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

    原文:http://andrewhfarmer.com/react-ajax-best-practices/

    如果喜欢本文,可以订阅沪江技术学院公众号。

    相关文章

      网友评论

        本文标题:翻译 | React AJAX最佳实践

        本文链接:https://www.haomeiwen.com/subject/ynzgvttx.html