前言
本文为意译,翻译过程中掺杂本人的理解,如有误导,请放弃继续阅读。
原文地址:Making Sense of React Hooks by Dan Abramov
这一周,Sophie Alpert和我在 React Conf大会上发表了有关于Hooks提案的演讲,随后 Ryan Florence进行了更加深入的探讨。
我强烈推荐大家去观看这个开幕式主题演讲,看看我们到底在尝试使用Hooks来解决什么样的问题。然而,花几乎一个小时去看视频,对于读者来说已经是一个很大的投资(更不用说这个总时长为1小时35分29秒的视频),所以,我决定简单地分享几个我对React Hooks的看法或者想法。
注意:Hooks还只是React的一个实验性的提案,你不需要马上就去学习它。同时也要注意,这个文章里面纯属是我个人的观点,跟 React Team没有任何的关联,请不要随意上纲上线。
正文
为什么是Hooks?
大家都知道,我们是依靠组件和自上而下的数据流来将一个巨大的应用化解为一些小的,独立的和可复用的代码块的。然而,因为逻辑是有状态,它不能被提取为一个函数或者组件,所以我们无法进一步地分解复杂的组件为小的,简单和可复用的组件。这就是人们常常说到的:“React无法帮助他们达成关注点分离。”
上面提到的情况还是挺常见的,这里面还包括动画,表单处理,关联外部数据和其他我们想单独在组件内部了完成的场景。当我们尝试仅仅依靠组件来解决这类的问题,往往都会以下面的结果告终:
- 难以测试和重构的巨大的组件。
- 在不同的组件和生命周期函数里面编写重复的逻辑代码。
- 采用了复杂的模式比如render props,高阶组件。
我们觉得Hooks是解决这些问题的最好方法。Hooks让我们将组件内的逻辑组织成可重用的独立单元。
这里是两个React用户演示使用React Hooks带来啥好处的截图和链接。
【Sunil Pai@threepointone】
【Pavel Prichodko@prchdk】
相比组件与组件之间,Hooks是在组件内实践了React的理念(明确的数据流和组合优于继承)。 这就是为什么我觉得Hooks天然符合React的组件模型。
不像render props和高阶组件的模式,Hooks没有引入额外的嵌套层到你的组件树中。同时,它也没有mixins的缺点。
如果你的第一反应是不喜欢Hooks的话,我建议你给它一个公平公正的机会,尝试着去使用它。我相信,你会喜欢它的。
Hooks是不是会让React变得臃肿吗?
在我们深入Hooks的细节之前,你可能会担心引入Hooks会带来一些额外的概念。这是一个相当正常的质疑。客观来说,学习Hooks短期内肯定会有一些认知上的成本,但是随着你越来越熟悉地使用,结果是相反的。(也就是说,到了后面,你能靠这个短期内收获的认知去长期获利,用中文来表达就是利在当今,功在千秋)。
假设,React community 拥抱Hooks提案,那么,它将会大大地减少你在开发React应用决策权衡时所涉及的众多概念。Hooks使得你只需要写函数,而不是频繁地在functions,classes,higher-order components和render props 众多概念之间切换。
在实现的大小方面,Hooks给React带了大概+1.5KB(min+gzip)的体积涨幅。虽然这并不少,但是采用Hooks可能会减小压缩包大小,因为使用它的代码比使用classes的等效代码更容易压缩。下面这个例子虽然看起来有点极端,但是它很多地演示了这其中的原因。
Let's also compare how well these minify
Hooks的引入并没有给React带来一些断崖式的升级。即使在新的代码中你采用了Hooks,现存的代码还是会一如既往地生效,它们不会受到影响。实际上,这就是我们常常推荐的做法--渐进式地使用,不要做任何大范围的重写。在一些关键代码上,不马上采用Hooks去编写,而是再观望一下,这是一个明智的做法。然而,如果你能将React@16.7 alpha版本用上去,并且将一些使用感谢反馈给我们,那么我们将会十分的感激。你可以将你的感想和想要反馈的问题发布到Hooks proposal和 report any bugs。
Hooks到底是什么?
在继续讨论Hooks之前,我们需要花点时间来回顾一下code reuse。
目前来说,在React应用中有很多方法来达成逻辑复用。我们可以编写一些计算型的纯函数来计算某些值;我们也可以编写一些components(function component 或者classes component)来实现复用。component更加强大,但是与此同时,它们也要负责渲染UI。这使得它们在复用非视觉层面上的逻辑时变得不太方便。最终,我们不得不引入一些复杂的模式来达成这个目的--高阶组件或者render props。假如在React生态里面,大家只有一种公认的复用代码的方式,那么React生态会不会变得更加的简单呢?
函数好像是复用代码方面的一个完美机制。通过将逻辑封装在函数里面来共用代码产生的成本是最小的。然而,函数里面,不能包含React state。在classes component里面,在不重构代码或者引入一层新的抽象层(比如说Observables)的前提下,你是很难将一些行为抽取出来的,比如:“watch window size and update the state”,“animate a value over time”。
而Hooks恰恰就是用来解决这些问题的。Hooks支持你在函数里面去使用React features(比如state,生命周期,context等)。而这一切,仅仅需要一次函数调用。React提供了一下内置的Hooks去让你使用React应用的构建基石--就是上面提到的React features。
因为Hooks仅仅是一个普通的javascript函数,所以,你可以将React内置的Hooks和你自己自定义的“custom Hooks”组合起来。你可以通过这种方法,将一些复杂的实现变成一行代码,并且在你的React应用中或者整个React community来分享它。
通过npm包来构建你的React应用
注意,从技术上来讲,custom Hooks并不属于React feature。不过,你自己实现的Hooks按理来说也要遵循Hooks的设计理念。
代码演示
(未完待续......)