> * 原文地址：[When Does a Project Need React?](https://css-tricks.com/project-need-react/)
> * 原文作者：本文已获原作者 [CHRIS COYIER](https://css-tricks.com/author/chriscoyier/) 授权
> * 译文出自：[掘金翻译计划](https://github.com/xitu/gold-miner)
> * 译者：[龙骑将杨影枫](https://github.com/stormrabbit)
> * 校对者：[Guangyuan (Charlie) Yang](https://github.com/yzgyyang)、[薛定谔的猫](https://github.com/Aladdin-ADD)

# 项目什么时候需要 React 框架呢？ #

你知道什么时候项目需要 HTML 和 CSS，因为这是项目的基础。什么时候用 JavaScript 也很清楚：当你需要只有它能提供的交互功能的时候。过去我们什么时候应该用代码库也很清楚：我们需要 jQuery 来帮助我们简化 DOM 操作，调用 Ajax，处理浏览器兼容问题；我们需要 Underscore 提供 JavaScript 没有的帮助函数（ helper functions ）。

但是随着对这些代码库的需求逐渐消失，我们看到很多新兴框架的大幅增长。我认为就不那么容易确定**何时需要它们**了。比如说，我们什么情况下需要 React 框架？

在众多的 JavaScript 框架中 —— Vue、Ember、Svelte ... 不管哪一个，我想以 React 框架为例子来探讨它适合什么项目。我明白这些框架并不完全相同，但是使用它们的时机应该是有一些共性的。

这是我的建议。

### ✅ 当项目中有大量的状态的时候 ###


即便“状态（state）”这个词也无法完全准确的表达我的意思。想象一下这些情况：

- 导航栏的哪个栏目正处于激活状态
- 一个按钮是否被禁用
- 输入框的值
- 哪一个下拉框是弹出的状态
- 何时加载某个区域
- 登陆的用户如何进行权限控制
- 用户编写的文章是已发布状态还是草稿状态


“业务逻辑” —— 我们经常处理的这类东西。状态也可能和内容直接相关：

- 一篇文章中所有的评论，以及零零碎碎的组成它们的东西。
- 当前正在查看的文章，以及该文章的一些属性
- 一系列相关的文章，以及这些文章的属性
- 一份作者列表
- 一份记录用户近期操作的活动日志

React 框架并没有帮助你**组织**这些状态，它只是说：我知道你需要处理状态的问题，所以我们不如把它设为 state 属性，通过编程的方式进行读写。


在有 React 框架之前，我们也许**考虑过**状态的定义，但是大部分时候并没有把它当作一个直接的概念去管理。


也许你听说过这个短语“单一数据源”？很多时候我们把 DOM 作为我们的单一数据源。比如说，你需要知道是否可以提交某个表单了。也许你会用 `$(".form input[type='submit']).is(":disabled")` 去检查一下，因为所有影响表单是否可提交的业务逻辑最终都会改变按钮的 disable 属性。所以按钮变成了你的 app 事实上的数据源。


或者说，你需要知道某篇文章的第一个评论者的名字，也许你会这样写 `$(".comments > ul > li:first > h3.comment-author).text()`，因为 DOM 是你唯一可以获得这些信息的地方。


React 框架这样告诉我们：

1. 我们把这些所有的东西都想像成状态（state）。

2. 我会为你做好一件事：把状态转换为一串 JSON 对象，这样的话处理起来很容易，也许你的服务端可以处理的很漂亮。

3. 更棒的是：你可以用这些状态（state）直接构建 HTML ，你根本不需要直接操作 DOM，我都替你处理了（也许比你亲自处理的要更快更好）。

### ✅ 对抗面条式代码 （Spaghetti） ###

这和我们刚才讨论过的状态有非常大的关系。

“面条式”代码，指的是代码的组织结构已经脱离你的掌控。再想象一下，假设有这么一个表单，它有一些专门处理表单内输入框的业务逻辑。该表单内有这么一个数字输入框，当这个输入框的值改变的时候，在旁边显示根据该值进行某些计算后的结果。这个表单可以被提交至服务端，因此也需要合法性检查，而也许合法性检查的代码位于其他地方的验证库中。也许在确定某处的 JavaScript 代码全部加载完之前，你还需要禁用此表单，而这个逻辑也在别的地方。也许当表单提交后，你还需要处理一些返回值。没有什么特别让人意外的功能，但是凑在一起就很容易让人蒙圈。如果这个项目由一个新的开发人员接手后，当他看到这个表单时他如何能捋清这些逻辑呢？

React 框架鼓励把东西打包成组件。所以这个表单要么自己是一个组件，要么由其他的小组件组成。每一个组件只处理与自己直接相关的逻辑。

React 框架说：**嗯，你不会直接看到 DOM 的变化，因为 DOM 是我的，你无法直接操作它**。为什么你不把这些东西想象成状态的一部分，当需要的时候就改变状态（state）。我会处理其他的事情，重新渲染需要被渲染的界面。

应该说，只有 React 框架还不足以解决面条式代码。因为状态也可能出现在各个奇怪的地方，或者状态起的名字很糟糕，或者用莫名其妙的方式调用。

以我有限的经验来看，Redux 库才能真正解决面条式代码的问题。Redux 说：我会处理**所有**重要的状态，都是全局的，不是组件依赖的。我才是唯一的数据源。如果你需要改变状态，就要采用特定的**仪式**（我听说它是这么叫的，而且我喜欢这么叫）。通过 reducers 和被分发的（dispatched） actions，所有的改变都会遵循这种仪式。

如果你准备在项目中加入 Redux（或者 Redux 的变种），那么你就可以和硬编码说再见了。通过加入 Redux 框架，组件会变的高内聚，也很容易理清整个需求的逻辑走向了。

### ✅ 要管理大量的DOM ###

手动处理 DOM 可能是引起面条式代码的最大原因。

1. 在这里插入一段 HTML ！

2. 在这里把某些东西扔出去！

3. 监听特定区域的特定事件（event）！

4. 在这里绑定一个新事件！

5. 又来了新内容。再次插入到 HTML 里，确保它绑定了正确的事件！

此类事情可以发生在一个 app 的任何地方、任何时间，这就造成了面条式代码。手动管理是不靠谱的，因为这么做的话又变成 DOM 数据源了。很难准确的知道任何给定的元素发生了什么，所以每个人只好直接查询 DOM ，做他们必须做的事情，顺便向上帝祈祷他们这么做没干扰到别人。

React 框架说：你不需要直接操作 DOM 。我用虚拟 DOM 来处理真实的 DOM。如果你想要操作 DOM，可以直接在虚拟 DOM 上操作。通过这种方式，所有的逻辑就有迹可循了。

管理**复杂的** DOM 是另一件适合 React 框架的事情。想象有一个聊天软件，当数据库接收到其他聊天者传递来的新聊天信息时，在聊天窗口里应该显示这些新的信息。否则你只能自己给自己聊天了！或者当聊天页面第一次被加载的时候，可以从本地数据库里找出几条旧信息显示出来，这样你立刻有东西可以看了。比如说这个[推特例子](https://twitter.com/mjackson/status/849636985740210177)。

### ❌ 只是因为，React 框架是目前最火的框架。 ###

学习新东西是很酷的，所以学习吧！

为了满足用户的需求而构建项目则需要更谨慎一点。

举个例子，一个博客**也许**没什么复杂的逻辑，一点也不符合应该使用 React 框架的情况。所以如果不是很适合的话，那么也许就是**很不**适合 React 框架。因为这么做引入了复杂的技术，依赖了很多根本没用到的东西。

在完全适合和完全不适合之间，如果这个博客是一个 SPA （“单页面应用”，不需要浏览器刷新），通过 headless CMS 获取数据构建该博客，并且具有出色的服务端渲染...好吧，也许又是 React 框架的领域。

如果是 web app CMS 创建的这种博客？也许用 React 是一个好选择，因为它也有一大堆的状态。

### ❌ 我就是喜欢 JavaScript ，就是想用它来编写任何东西。 ###

我经常安利周围的人：学习 JavaScript。因为 JavaScript 的知识太丰富了。它能做很多很多的事情，也有很多的工作机会，所以好好学习 JavaScript 永远不会过时。

只有在最近的网络技术历史里，Javascript 才可以做所有的事情。你通过 Node.js 构建服务端，也有很多项目可以通过 JavaScript 处理 CSS。现在通过 React 框架，你还可以通过 JavaScript 来写 HTML。

万物归于 JavaScript！JavaScript 万岁！

React 确实碉堡了，但是你可以用 React 并不意味着你必须用 React 。并不是所有的项目都必须使用它 ，而且事实上，有相当一部分有可能压根不需要它。

### ☯️ 这就是我所知道的。 ###

（**是**或者**否**都可以找到合适的图标来表达，但是想表达**也许**的意思就比较复杂）（译者注： 指作者此处用太极的图标表示**也许**的意思。）

你在学习，太好了。每个人都在学习，所以坚持学习吧。你知道的越多，你越知道该应该用什么技术更好。

但是很多时候你只能以现有的技术来构建项目，所以我也不会反复强调这一点。

### ☯️ 这就是工作。 ###

在给定的任何项目中，不是每个人都决定应该底用什么技术。希望随着时间的增长，你可以更大层度上的影响决策。Eden 说她[花了两年的时间研究 Ember](https://twitter.com/edenthecat/status/849640183360352257)，因为这就是她的工作。没有任何冒犯的意思，但是拿人钱财就得替人消灾。Ember 也许比较适合这些项目。

---

> [掘金翻译计划](https://github.com/xitu/gold-miner) 是一个翻译优质互联网技术文章的社区，文章来源为 [掘金](https://juejin.im) 上的英文分享文章。内容覆盖 [Android](https://github.com/xitu/gold-miner#android)、[iOS](https://github.com/xitu/gold-miner#ios)、[React](https://github.com/xitu/gold-miner#react)、[前端](https://github.com/xitu/gold-miner#前端)、[后端](https://github.com/xitu/gold-miner#后端)、[产品](https://github.com/xitu/gold-miner#产品)、[设计](https://github.com/xitu/gold-miner#设计) 等领域，想要查看更多优质译文请持续关注 [掘金翻译计划](https://github.com/xitu/gold-miner)。
