- 原文地址:When Does a Project Need React?
- 原文作者:CHRIS COYIER
- 译文出自:掘金翻译计划
- 译者:龙骑将杨影枫
- 校对者:Guangyuan (Charlie) Yang、薛定谔的猫
项目什么时候需要 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 框架这样告诉我们:
-
我们把这些所有的东西都想像成状态(state)。
-
我会为你做好一件事:把状态转换为一串 JSON 对象,这样的话处理起来很容易,也许你的服务端可以处理的很漂亮。
-
更棒的是:你可以用这些状态(state)直接构建 HTML ,你根本不需要直接操作 DOM,我都替你处理了(也许比你亲自处理的要更快更好)。
对抗面条式代码 (Spaghetti)
这和我们刚才讨论过的状态有非常大的关系。
“面条式”代码,指的是代码的组织结构已经脱离你的掌控。再想象一下,假设有这么一个表单,它有一些专门处理表单内输入框的业务逻辑。该表单内有这么一个数字输入框,当这个输入框的值改变的时候,在旁边显示根据该值进行某些计算后的结果。这个表单可以被提交至服务端,因此也需要合法性检查,而也许合法性检查的代码位于其他地方的验证库中。也许在确定某处的 JavaScript 代码全部加载完之前,你还需要禁用此表单,而这个逻辑也在别的地方。也许当表单提交后,你还需要处理一些返回值。没有什么特别让人意外的功能,但是凑在一起就很容易让人蒙圈。如果这个项目由一个新的开发人员接手,当他看到这个表单时如何能捋清这些逻辑呢?
React 框架鼓励把逻辑封装进组件。所以这个表单要么自己是一个组件,要么由其他的小组件组成。每一个组件只处理与自己直接相关的逻辑。
React 框架说:嗯,你不会直接看到 DOM 的变化,因为 DOM 是我的,你无法直接操作它。为什么你不把这些东西想象成状态的一部分,当需要的时候就改变状态(state)。我会处理其他的事情,重新渲染需要被渲染的界面。
应该说,只有 React 框架还不足以解决面条式代码。因为状态也可能出现在各个奇怪的地方,或者状态起的名字很糟糕,或者用莫名其妙的方式调用。
以我有限的经验来看,Redux 库才能真正解决面条式代码的问题。Redux 说:我会处理所有重要的状态,都是全局的,不是组件依赖的。我才是唯一的数据源。如果你需要改变状态,就要采用特定的仪式(我听说它是这么叫的,而且我喜欢这么叫)。通过 reducers 和被分发的(dispatched) actions,所有的改变都会遵循这种仪式。
如果你准备在项目中加入 Redux(或者 Redux 的变种),那么你就可以和硬编码说再见了。通过加入 Redux 框架,组件会变的高内聚,也很容易理清整个需求的逻辑走向了。
要管理大量的DOM
手动处理 DOM 可能是引起面条式代码的最大原因。
-
在这里插入一段 HTML !
-
在这里把某些东西分离出去!
-
监听特定区域的特定事件(event)!
-
在这里绑定一个新事件!
-
又来了新内容。再次插入到 HTML 里,确保它绑定了正确的事件!
此类事情可以发生在一个 app 的任何地方、任何时间,这就造成了面条式代码。手动管理是不靠谱的,因为这么做的话又变成 DOM 数据源了。很难准确的知道某个给定的元素发生了什么,所以每个人只好直接查询 DOM ,做他们必须做的事情,顺便向上帝祈祷他们这么做没干扰到别人。
React 框架说:你不需要直接操作 DOM 。我用虚拟 DOM 来处理真实的 DOM。如果你想要操作 DOM,可以直接在虚拟 DOM 上操作。通过这种方式,所有的逻辑就有迹可循了。
管理复杂的 DOM 是另一件适合 React 框架的事情。想象有一个聊天软件,当数据库接收到其他聊天者传递来的新聊天信息时,在聊天窗口里应该显示这些新的信息。否则你只能自己给自己聊天了!或者当聊天页面第一次被加载的时候,可以从本地数据库里找出几条旧信息显示出来,这样你立刻有东西可以看了。比如说这个推特例子。
只是因为,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,因为这就是她的工作。没有任何冒犯的意思,但是拿人钱财就得替人消灾。Ember 也许比较适合这些项目。