何时需要 React?

Avatar of Chris Coyier
Chris Coyier

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 200 美元的免费额度!

您知道何时一个项目需要 HTML 和 CSS,因为它们是所有项目的必备。何时需要 JavaScript 也相当清楚:当您需要交互性或某些只有 JavaScript 才能提供的功能时。过去,我们何时需要库也相当明确。我们使用 jQuery 来简化 DOM 操作、Ajax 和处理 JavaScript 的跨浏览器问题。我们使用 Underscore 来获得 JavaScript 本身不具备的辅助函数。

随着对这些库的需求逐渐减少,以及我们看到大量新的框架涌现,我认为何时需要使用它们变得不再那么清晰了。在什么情况下我们需要 React?

我只是在这里使用 React 作为某种大型 JavaScript 框架的占位符。Vue、Ember、Svelte……等等。我理解它们并不完全相同,但我发现何时需要使用它们同样模糊不清。

这是我的看法。

✅ 因为存在大量状态。

即使“状态”这个词也有些模糊。想象一下以下情况:

  • 哪个导航项处于活动状态
  • 按钮是否处于禁用状态
  • 输入框的值
  • 哪些手风琴部分已展开
  • 某个区域是否正在加载
  • 已登录的用户及其所属团队
  • 用户正在处理的内容是已发布还是草稿

我们经常处理的“业务逻辑”之类的东西。状态也可以是纯粹的内容

  • 文章的所有评论及其构成部分
  • 当前查看的文章及其所有元数据
  • 相关文章的数组及其元数据
  • 作者列表
  • 用户最近操作的活动日志

React 不会帮助您组织这些状态,它只是说:我知道您需要处理状态,所以让我们将其称为状态,并提供以编程方式设置和获取该状态的方法。

在 React 之前,我们可能考虑过状态,但大多数情况下,并没有将其作为一个直接的概念来管理。

也许您听说过“单一数据源”这个短语?很多时候,我们将 DOM 视为我们的单一数据源。例如,假设您需要知道网站上的表单是否可以提交。也许您会检查 $(".form input[type='submit']).is(":disabled"),因为处理表单是否可以提交的所有业务逻辑最终都会更改该按钮的 disabled 属性。因此,该按钮成为了应用程序状态的事实上的数据源。

或者假设您需要找出文章中第一个评论作者的姓名。也许您会编写 $(".comments > ul > li:first > h3.comment-author).text(),因为 DOM 是唯一知道此信息的地方。

React 告诉我们:

  1. 让我们开始将所有这些东西都视为状态。
  2. 我还可以说得更进一步:状态是一块 JSON 数据,因此易于使用,并且可能与您的后端很好地配合。
  3. 更进一步地说:您可以使用状态的片段构建 HTML,并且根本不需要直接处理 DOM,我会为您处理所有这些(并且可能比您做得更好/更快)。

✅ 打击意大利面条代码。

这与我们刚才讨论的状态问题密切相关。

“意大利面条”代码是指代码组织和结构失控的情况。再次想象一下网站上的表单。它具有一些专门处理其中输入项的业务逻辑。也许有一个数字输入框,当它发生变化时,会在它旁边显示一些计算结果。表单也可以提交,并且需要进行验证,因此此代码可能位于其他地方的验证库中。也许您会在确保所有 JavaScript 加载完成后再禁用表单,并且该逻辑位于其他地方。也许当表单提交时,您会获得数据,并且需要逻辑和处理。这里没有什么特别令人惊讶的地方,但您可以看到这很快就会变得混乱。项目中的新开发人员如何查看该表单并推断出所有正在发生的事情?

React 鼓励将事物构建成模块。因此,此表单很可能本身就是一个模块,或者由其他更小的模块组成。它们中的每一个都将处理与其直接相关的逻辑。

React 说:好吧,您将不会直接监视 DOM 以进行更改等操作,因为 DOM 是我的,您不能直接使用它。为什么不开始将这些东西视为状态的一部分,在需要时更改状态,我会处理其余的事情,重新渲染需要重新渲染的内容。

应该说 React 本身并不能完全解决意大利面条代码问题。您仍然可以在各种奇怪的地方存储状态,为事物命名不当,并以奇怪的方式连接事物。

根据我有限的经验,Redux 是真正解决意大利面条代码问题的工具。Redux 说:我会处理所有重要的状态,完全全局化,而不是模块化。我是绝对的数据源。如果您需要更改状态,则需要进行相当多的仪式(我听说过这种说法,并且我喜欢它)。有 reducers 和 dispatched actions 等等。所有更改都遵循该仪式。

如果您走 Redux 的道路(当然,它还有各种变体),最终会得到非常可靠的代码。破坏代码变得更加困难,并且有清晰的线索可以遵循,了解所有内容是如何连接在一起的。

✅ 大量 DOM 操作。

手动处理 DOM 可能是导致意大利面条代码的最主要原因。

  1. 在此处注入 HTML!
  2. 在此处删除某些内容!
  3. 监视此区域的此事件!
  4. 在此处绑定新的事件!
  5. 新的传入内容!再次注入!确保它具有正确的事件绑定!

所有这些事情都可能在已出现意大利面条代码的应用程序的任何时间、任何地方发生。真正的组织性已被放弃,并且 DOM 又成为了数据源。很难准确地知道任何给定元素正在发生什么,因此每个人都只是询问 DOM,做他们需要做的事情,并祈祷不会搞乱别人的事情。

React 说:您不能直接处理 DOM。我有一个虚拟 DOM,我处理它。事件直接绑定到元素,如果您需要它执行超出此模块中直接可处理内容的操作,您可以以某种仪式的方式在更高阶的模块中调用事物,但这样,就可以追踪到面包屑痕迹。

复杂的 DOM 管理是另一回事。想象一个聊天应用程序。新的聊天消息可能会出现,因为实时数据库从其他聊天者那里获得了新的数据,并且一些新消息已到达。或者您自己输入了一条新消息!或者页面正在首次加载,并且旧消息正在从本地数据存储中提取,以便您立即看到一些内容。这是一个 Twitter 线程,可以说明这一点。

❌ 仅仅因为它是最新潮流。

为了学习而学习某件事很棒。去做吧。

为客户和真实用户构建项目需要更谨慎的考虑。

例如,博客可能没有任何问题,也不符合任何使 React 成为合适选择的场景。而且,因为它不适合,所以它可能适合,因为它引入了不必要的复杂技术和依赖项。

然而,存在灰色地带。如果该博客是一个 SPA(“单页应用程序”,例如没有浏览器刷新),它由来自无头 CMS 的数据构建,并且具有花哨的服务器端渲染……那么它可能又回到了 React 的领域。

制作该博客的 Web 应用 CMS?由于所有状态的存在,它可能是 React 的一个好选择。

❌ 我只是喜欢 JavaScript,并且想用它编写所有内容。

人们被告知,或者说,我也告诉过人们:学习 JavaScript。它非常庞大。它为各种事物提供动力。它有很多工作机会。它不会消失。

直到最近的网页发展历史,才有可能完全不离开 JavaScript。服务器端有 Node.js。有很多项目将 CSS 从混合中剔除,并通过 JavaScript 处理样式。而使用 React,你的 HTML 也在 JavaScript 中。

全是 JavaScript!向 JavaScript 致敬!

这当然很酷,但是,再次强调,仅仅因为你可以,并不意味着你应该这样做。并非所有项目都需要这样做,事实上,大多数项目可能都不需要。

☯️ 这就是我所知道的。

(有不错的表情符号表示“是”和“否”,但“也许”就比较难找了!)

你正在学习。太棒了。每个人都在学习。继续学习。你了解的越多,就能做出越明智的关于使用哪种技术的决策。

但有时你必须用你所知道的知识来构建,所以我不会因为这个而批评你。

☯️ 这就是工作所在的地方。

并非每个人都能直接决定在任何给定的项目中使用什么技术。希望随着时间的推移,你在这方面会有影响力,但这需要时间。Eden 说她 在 Ember 上工作了 2 年,因为那里有工作机会。这没什么坏处。每个人都需要赚钱,而且 Ember 可能非常适合这些项目。