为什么我从 AngularJS 切换到 React
已发表: 2022-03-112011 年,当我的代码开始混杂 jQuery 选择器和回调时,AngularJS 成为了救命稻草,它有助于更好地管理、快速开发和更多开箱即用的功能。 AngularJS 的双向绑定和“模型作为单一事实来源”的理念让我大吃一惊,并减少了整个应用程序中的数据冗余。
然而,随着时间的推移,我发现 AngularJS 也有它自己的一些痛点。 最终,这些让我感到非常沮丧,以至于我开始四处寻找替代解决方案。
AngularJS 1.x 中的痛点
用于执行的 DOM
Angular 的执行流程严重依赖 DOM。 在应用程序的默认引导中,它会扫描 DOM 并使用指令优先级对其进行编译,这使得调试和测试执行顺序变得困难。
它自己的依赖注入
JavaScript 没有自己的包管理器和依赖解析器。 但最近,AMD、UMD 和 CommonJS 等实现已经很好地解决了这个问题。 遗憾的是,AngularJS 并没有派上用场。 相反,它引入了自己的依赖注入 (DI)。 尽管有使用 RequireJS 的非官方 AngularJS DI 实现。
双向绑定是一把双刃剑
使用双向绑定很诱人,但是随着组件复杂性的增加,它可能会导致性能灾难。
双向绑定如何影响性能? 好吧,JavaScript ES5 没有任何实现来通知其变量或对象的任何更改,因此 Angular 使用称为“脏检查”的东西来跟踪数据更改并将其与 UI 同步。 在 Angular 的范围($digest 循环)内执行任何操作之后执行脏检查,这会随着绑定数量的增加而导致性能下降。
双向绑定的另一个问题是页面上的许多不同组件都能够更改数据,从而导致数据输入的多个来源。 如果处理不好,可能会导致模棱两可的情况。 但公平地说,这纯粹是一个实施问题。
Angular 有自己的世界
Angular 中的每个操作都必须经过其摘要周期,否则您的组件将无法与您的数据模型同步。 因此,如果您使用任何第三方现有的 JavaScript 库,如果它涉及数据更改,则需要使用 Angular 的 $apply 函数包装它,或者如果它是实用程序库,则需要将其转换为服务。 这就像为 Angular 重新发明每个可用的 JavaScript 模块。
太多的概念和陡峭的学习曲线
学习 Angular 需要学习大量的概念,包括模块、控制器、指令、范围、模板、链接函数、过滤器和依赖注入。
认识反应
React 是来自 Facebook 和 Instagram 的新开源 JS 库,是编写 JavaScript 应用程序的另一种方式。 当它在 2013 年 5 月的 JSConf EU 上推出时,观众对其“单向数据流”和“虚拟 DOM”等一些设计原则感到震惊。
React 官方网站说,“React 是一个用于构建用户界面的 JavaScript 库”,是的,只有界面,没有别的。 它不是像 AngularJS 这样的框架。 但是您可以编写或多或少与 Angular 指令相比较的自包含组件。 快速概览
React 重新思考了 Web 开发中的最佳实践。 Reach 鼓励单向数据流,并相信组件是由数据驱动的状态机的理念。 尽管大多数其他框架都喜欢使用 DOM 并直接操作它,但 React 讨厌 DOM 并努力保护开发人员免受它的影响。 React 仅提供定义任何 UI 组件所需的基本 API,没有其他任何东西。 达遵循 UNIX 理念:小而美。 做一件事并做到最好。
这是Pete Hunt(来自Instagram团队)对两者进行的非常好的比较
它只是一个图书馆。 我们需要一个带有 React 的框架吗?
简短的回答:您的选择。
使用 React,您可以构建用户界面,但我们仍然需要管理依赖项、进行 AJAX 调用、应用数据过滤器。 如果我们确实需要一个框架,为什么要抛弃 AngularJS?
框架是一组包和一组规则。 如果我不需要一些包,或者想换另一个包怎么办。 我该怎么做? 我们需要一个包管理器。 我们如何在 AngularJS 中管理包? 这是你的选择,但 Angular 有它自己的世界。 您需要将每个外部包包装到 Angular 的世界中,然后使用它。 但是 React 只是 JavaScript,任何用 JavaScript 编写的包都不需要在 React 中进行任何包装。
所以,如果我们从像 npm 这样的包存储库中选择我们自己的包并按照我们喜欢的方式组织它们会更好。 好消息是 React 鼓励使用 npm,它有很多现成的包。 要开始使用 React,您可能希望使用这些全栈入门工具包之一
反应的优点
那么为什么我真的切换到 React 呢?

反应速度很快!
React 采用与其他框架不同的方法。 它不允许您直接使用 DOM。 相反,它在 JavaScript 逻辑和实际 DOM 之间引入了一层虚拟 DOM。 这有助于大大提高速度。 在连续渲染时,React 对虚拟 DOM 执行差异化,并仅更新需要更新的真实 DOM 部分。
Virtual DOM 还有助于解决跨浏览器问题,因为它提供了一个统一的跨浏览器 API,甚至可以在 Internet Explorer 8 中使用。(呸!)
一切都是组件(UI 小部件)
编写自包含的 UI 组件可将您的应用程序模块化并分离每个关注点。 每个组件都可以单独开发和测试,然后使用其他组件来提高可维护性。
单向数据流为赢!
Flux 是一种用于在 JavaScript 应用程序中创建单向数据层的架构。 它是在 Facebook 与 React 视图库一起设计的。 它使开发更简单,更容易追踪和修复错误。 Flux 更多的是一个概念,而不是一个实现。 它也可以在其他框架中实现。 Alex Rattray 在 React 中使用 Backbone Collection 和 Model 实现了一个非常好的 Flux。
JavaScript,仅此而已
现代 Web 应用程序的工作方式与传统 Web 不同。 视图层需要在不影响服务器的情况下通过用户交互进行更新。 因此 View 和 Controller 需要相互依赖。 许多其他框架使用 Handlebars 和 Mustache 等模板引擎作为其视图层,但 React 认为这两个部分是如此相互依赖,以至于它们必须驻留在一个地方,而不使用任何第三方模板引擎,并且不离开JavaScript。
同构 JavaScript
单页 JavaScript Web 应用程序的最大缺点是它在被搜索引擎抓取时有限制。 React 有一个解决方案。 React 可以在将应用程序发送到浏览器之前在服务器上预渲染应用程序,它还可以从服务器预渲染的静态内容将相同的状态恢复到实时应用程序中。 由于搜索引擎爬虫严重依赖服务器响应而不是 JavaScript 执行,因此预渲染此类应用程序有助于搜索引擎优化。
React 与 RequireJS、Browserify 和 Webpack 配合得很好
在构建大型应用程序时,非常需要加载器和捆绑器。 不幸的是,当前版本的 JavaScript 没有提供模块捆绑器或加载器,尽管它在即将发布的 EcmaScript 6 (System.import) 版本中提出。 幸运的是,我们有一些替代品,例如 RequireJS 和 Webpack,它们非常不错。
React 是使用 Browserify 构建的,但如果您希望注入图像资源并编译 LESS 或 CoffeeScript,那么 Webpack 可能是更好的选择。
我有些痛苦地切换到了 React。
由于 AngularJS 是一个框架,它附带了很多好东西,其中包括 $http 服务中的 AJAX 包装器、作为承诺服务的 $q、ng-show、ng-hide、ng-class 和 ng-if 作为控制语句为模板。
React 不是一个框架,而是一个用于构建 UI 的库,因此您需要自己考虑所有其他部分。 我正在开发一个可以与 React 一起使用以简化开发的开源项目,并且社区也在积极贡献类似的可重用组件。
React-components.com 是一个非官方的目录网站,您可以在其中找到此类开源组件。
React 的理念不鼓励您使用双向绑定,这在处理表单元素和可编辑数据网格时会带来很多痛苦。 但是,当您开始了解 Flux 数据流和 Store 时,事情会变得更加清晰、简单和容易。
React 是新的,因此社区需要一些时间来发展。
Angular 近来非常受欢迎,并且有大量可用的扩展,如 AngularUI 和 Restangular。 React 的开源社区是新的,但它正在快速增长,并带有 React Bootstrap 之类的扩展。 我们拥有更多可用组件只是时间问题,并且 React 可以轻松用于快速 Web 应用程序开发。
结论
如果你以前用过 AngularJS,那么你一开始可能会讨厌 React,主要是因为它是单向的数据流,并且缺乏你需要自己处理许多其他事情的“框架”。 但是一旦你熟悉了 Flux 设计模式和 React 的哲学,你就会意识到它的美妙之处。
Facebook 和 Instagram 都使用 React。 Github 的新 Atom 编辑器是使用 React 构建的。 即将推出的 Yahoo Mail 正在 React 中重新构建。 您还需要哪些示例? 今天就试试 React。