react to(React.js大型复杂应用实战:Codecademy)

2014年八月,Codecademy为了更新用户的学习体验,决定采用Facebook的React.js库,这是一个用于编写JavaScript UI的类库。在开始阶段,我们的问题是很难找到React在复杂应用中应用的示例,例如像Codecademy这样复杂的应用。因为大多数的教程都是针对小型示例应用上的特性,而不是针对在开发大型应用中更常见的问题。在本文中,我不仅会对React的使用进行一番概述,还会特别说明在大型web应用程序中使用React的某些特别注意事项。

React是什么?

简单来说:React是一个使用JavaScript创建用户界面的代码库。与编写用户界面常见的方式不同,React将资源之家】每日免费更新最热门的副业项目资源每个UI元素视为一个抑制的状态机。它并不是类似于AngularJS这样的“框架”。虽然Facebook有时会将React描述为“MVC中的V”,但我发觉这一描述并没有什么帮助,因为React应用并不需要遵守MVC模型。React能够帮助你创建快速的用户界面,处理复杂的交互,而无需编写大量糟糕的代码。

如果你打算在工作中使用React,你需要了解以下特性:

React会为你处理DOM”

DOM操作的开销很大,而React的吸引力很大程度上来自于它对这一问题的处理方式。React通过对自身虚拟DOM的维护,只在需要时进行重新渲染,将DOM操作的数量降至了最低,这要归功于React中高性能的比较操作的实资源之家】每日免费更新最热门的副业项目资源现。

这就意味着你很少会需要直接与DOM打交道,与之相反,React会替你处理DOM的操作。这一特性也是诸多React设计的基础。如果你打算滥用React的API,或是打算按照自己的方式进行改动,那有可能会影响到React对DOM的理解。

该特性也使得使用Node.js进行内置的服务端渲染成为可能,这一点就使你能够轻易地创建对于SEO友好的页面。

React使用声明式风格以及组件”

在React中,所有的组件都必须继承自Component类。组件中包含了属性(由父类决定)和状态(能够自行改变,通常是基于用户行为进行改变),组件的渲染和行为应当完全由它们的状态和属性所决定(而不依赖于任何其它值),因此资源之家】每日免费更新最热门的副业项目资源组件就是状态机。这一模型鼓励使用者创建模块化的UI,并且在实践中能够简化UI的操作与创建工作。

React将标记紧密地结合在JavaScript中”

虽然在JavaScript中编写HTML代码听起来很奇怪,但在React中这是一种自然的选择。JSX是原生的JS与HTML标记相结合的一种语言,对于它的使用是可选的,但我强烈建议你选择这种方式。React认为,由于你的标记已经紧密地结合在控制这些标记的JavaScript中,因此可以将它们安置在同一个文件中,我也同意这一看法。

单向信息流动”

这一点更多的是一种通用的React模式,而不是一种严格的规则。信息的流动在React中倾向于单向流动。在本文资源之家】每日免费更新最热门的副业项目资源的稍后部分中,当我们开始考虑在大型应用程序中如何处理信息流动时,会再次提及这一模式。

解析React应用程序

为了让这些原则显得更为清晰,让我们看看Codecademy的学习环境是如何使用React进行构建的。

学习环境

正如你在这个屏幕截图中所看到的一样,主要的学习环境由多个不同的UI元素所组成。某些元素是始终展现在页面上的,例如header、menu和navigation。而有些组件会根据当前的练习的不同,处于显示或是不显示的状态。比方如,根据课程的不同,web浏览器、命令行和代码编辑器可能会进行混合或是匹配。

创建该界面的逻辑解决方案是为各个部分创建React组件。在下面的屏幕截图中,我将特别指出资源之家】每日免费更新最热门的副业项目资源主要的React组件:

学习环境以及对应的组件

每个组件都有可能包含多个子组件:比方如,屏幕左方的Lesson面板实际上就包含了多个组件:

组成Lesson组件的各个子组件

在这个示例中,我们将使用React以决定哪些组件应该显示在该lesson面板中。举例来说:

只有在用户已登录的前提下,才会显示“Report a Problem”按钮

只有在该练习中包括测试的情况下,才会显示Instructions部分

此外,React会处理该组件与其它组件之间的信息流动。整个学习环境对应着一个父组件,该组件会持续跟踪多个状态,例如当前用户处于哪个练习中。父组件会为子组件的属性进行相应的赋值,以决定这些子组件如何显示。资源之家】每日免费更新最热门的副业项目资源

现在,让我们来看一个组件通信的示例,以下组件来自经过大量简化后的组件树结构:

LearningEnvironment

CodeEditor

RunButton

ErrorDisplayer

Navigation

与代码提交相关的某些组件

如果某个用户打算运行他的代码,我们该如何处理这一工作流?我们将尝试对他们提交的代码进行测试,然后显示错误信息,或是允许用户继续下一题。以下是某个可能发生的工作流:

当用户单击RunButton之后,该组件会在事件的调用中,通过回调方式通知它的父组件CodeEditor。

CodeEditor组件会通过另一个回调函数通知它的父组件,即Learning Environment组件,资源之家】每日免费更新最热门的副业项目资源并将用户的当前代码传递给父组件。

LearningEnvironment组件将针对用户的代码进行测试。

根据结果的不同……

LearningEnvironment组件会对CodeEditor中的属性errorMessage赋值,CodeEditor则会依次为它的子组件ErrorDisplayer中的属性errorMessage赋值。

如果用户已经完成了该练习的所有测试,LearningEnvironment组件就会为Navigation组件中的属性progress赋值。

如果我们的组件都能够像在LearningEnvironment组件中的render方法一样进行声明(同样进行了大量简化),那么就可以通资源之家】每日免费更新最热门的副业项目资源过一个单一的函数调用实现整个UI的更新:

请记住,React中混合了JavaScript和HTML标记。在这个例子中,render方法定义了一个LearningEnvironment组件,其中包括了一个CodeEditor组件和一个Navigation组件。

我们可以更新LearningEnvironment组件的状态,它会触发组件的重绘,并在必要时更新子组件。

这就是全部的代码了。React以一种优雅而简单的方式替我们处理UI的更新操作。

大型应用程序中的考虑因素:信息流动

正如我之前所说的一样,React不一定要遵循MVC模型,实际上,你可以按照任何你喜欢的方式处理信息流动,但你需要一种确切的信息策资源之家】每日免费更新最热门的副业项目资源略。为了让属性的变化传递给子-子-子-子-子组件,你是否需要将该属性一路传递下去,哪怕中间的那些子组件完全不需要了解该属性?如果该叶子节点接受用户输入,它又该如何将这一变更通知它的父-父-父-父组件呢?

在大型应用程序中,这种处理方式是很令人受挫的。即使是在以上那个简单的示例中,Run按钮该如何与LearningEnvironment组件之间传递用户的行为呢?我们需要传递回调函数,但这种方式很难写出真正模块化、可重用的组件。

Codecademy的解决方案是通过创建通信适配器(Adapter),以管理各别组件间的信息流动。与传递回调函数的方式不同,高层次的组件,例如CodeEditor会接收到一个资源之家】每日免费更新最热门的副业项目资源Adapter,它为重要的通信任务提供了一种单一的接口。举例来说,当CodeEditor处于显示状态时,LearningEnvironment会创建一个Adapter,它能够生成和处理与用户提交代码相关的事件。

这种方式也不是完全没有缺陷的,我也在React大会的演讲中针对这一点进行了详细的论述。我的主要观点在于,无论你如何处理组件树中的信息流动,你的团队都应该坚持一种一致的策略。

大型应用程序中的考虑因素:整合

React的上手非常简单,但要在你的工作流中高效地使用它,你需要一些工具的支持。举例来说,我们使用了以下工具:

用一段脚本对.jsx文件的本地文化进行监控,并在必要时对它们进行重新编译

一个独资源之家】每日免费更新最热门的副业项目资源立的node.js服务器,用于处理服务端的展示

用于在需要时自动生成新组件文件的开发者工具

以上这些工具都不是非常复杂。对于.jsx的监控来说,Gulp是一个很好的选择,不过我们选择了使用Go语言自行编写脚本。我们使用了一个简单的批处理脚本负责生成新的组件文件,这种方式也能够确保命名规范。如果你打算使用一个node.js服务器以负责服务端展示,你需要当心的是,要强制require.js能够获取到React代码中的变更可能会有些困难,因此我们创建了一个监控器,让它在必要时重启node服务器。

为什么使用React?

在我们重新设计整个学习环境时,我们需要决定选择使用哪一套工具或框架。我们最终选择了Rea资源之家】每日免费更新最热门的副业项目资源ct,对这一决定我们感到非常满意。

我们对于React的欣赏之处主要在于以下几个方面:

它经过了实战检验

React已经在Facebook和Instagram的生产环境中得到应用,因此我们对于它的性能和可靠性很有信心。目前为止,它在我们的平台上同样表现良好,我们也没有遇到过任何严重的问题。

组件化的方式便于理解

React对每个独立的组件进行单独处理,这些组件会按照它内部的状态进行展现,因此对于某一时刻应该发生什么事,很容易形成概念化的理解。你的应用程序会有效地成为一个大型状态机。这意味着你可以单独测试UI中的每个片段,同样可以自由地添加新组件,而无需担心会影响整个应用程序中其它部分的代码。

SEO非常容资源之家】每日免费更新最热门的副业项目资源易实现

因为React本身就支持服务端展现,因此在搜索引擎看来,你提供的是一个基本已完成的页面,这对于SEO来说是一个极大的优势,而所需的工作量非常小。的确,这一点必需由Node完成。由于Codecademy的主应用是由Rails编写的,因此我们搭建了一个独立的Node服务器,专门用于处理React的展现。

React能够兼容遗留代码,并且它的灵活性足以应对未来

虽然采用一整套框架的确是一件大事,但你也可以慢慢地尝试将React添加到现有的代码库中。与之类似,如果将来我们需要移除React,我们也可以轻易地实现这一点。在Codecademy,我们首先决定完全使用React来编写一个全新的项目,以便尝资源之家】每日免费更新最热门的副业项目资源试它的功能,并学习如何以最佳的方式使用它。这个项目很成功,因此我们现在基本上在所有的新UI元素中都使用React了。我建议你首先做些功课,创建一些实验项目,然后再考虑怎样让React适应于你的现有代码库。

不必担心编写样板代码了

在编写样板代码上所花的时间越少,就意味着你可以将更多的时间花在更有意义的问题上了。从这个角度上来说,React是个既简洁又轻量级的类库。以下代码是创建一个新的组件所需的最少代码:

简短且切题,还有什么不满意的?

我们的社区正在成长

React社区的发展非常迅速。当你遇到各种问题时,你可以和许多社区成员讨论这一问题。并且,由于许多公司都已经在生产环境中使用了React(仅举几例,资源之家】每日免费更新最热门的副业项目资源Facebook、Instagram、Yahoo!、Github和Netflix),因此我们并不独孤。

总结

React是一个轻量级、强大,并且经过实战检验的使用JavaScript创建用户界面的类库。它不是一个框架,而是一个强大的工具,或许会改变你进行前端开发的方式。我们认为它对于我们的前端开发来说,作用之大是难以置信的,而我们对于自己的选择也感到相当满意。对我自己来说,使用React进行工作至少是极大地影响了我思考编写用户界面的方式。我也乐于看到React的不断成长:现在Facebook已经通过React Native将React的功能带到移动开发上了,我想它的未来一定会是一片光明。

如果你打算资源之家】每日免费更新最热门的副业项目资源上手使用React,它的教程是一个不错的逻辑起点。互联网上也有着大量介绍React中的关键概念的帖子。不要停下脚步,学习钻研,尝试着创建些什么,然后看看你对于React这种前端开发方式是怎么想的。我们非常乐于聆听你的想法。

关于作者

Bonnie Eisenman是一位来自于Codecademy.com的软件工程师。她最近刚刚从普林斯顿大学的计算机科学专业毕业。她对硬件也有一定兴趣,在业余时间喜欢从事一些Arduino方面的工作,以及乐曲编辑。她的Twitter帐号是@brindelle

【QCon北京2015】永不止步的前端专题,由蚂蚁金服体验技术部负责人王保平(玉伯)主持,重点讨论:移动 H5资源之家】每日免费更新最热门的副业项目资源 应用的开发,包括 Web 与 Native 的融合;企业平台类富应用的开发,涵盖 Angular、React、Polymer 等技术方向;前端工程与质量体系的建设,关注团队的高效协同、品质把控;前端工程师的历史转身,何去何从。敬请期待。

发表回复

后才能评论