原文:Introducing Hooks

Hooks是React 16.8的新特性。这些特性让你不必专门写class组件,来使用state和其他React特性。

  1. import React, { useState } from 'react';
  2. function Example() {
  3. // Declare a new state variable, which we'll call "count"
  4. // 声明新的state变量,我们叫它count
  5. const [count, setCount] = useState(0);
  6. return (
  7. <div>
  8. <p>You clicked {count} times</p>
  9. <button onClick={() => setCount(count + 1)}>
  10. Click me
  11. </button>
  12. </div>
  13. );
  14. }

新的函数“useState”就是我们要学习的第一个Hook,不过这个例子目前还是个难题。它现在还没什么意义,先别担心!
你可以在下一讲直接开始学习Hooks。本文中,我们将会继续解释我们为啥由在React中加了Hooks,也将解释它们怎么样能帮助我们写出更好的程序。

注意 React 16.8.0是支持Hooks的第一个版本。当更新是,别忘了更下全部的包,包括React DOM。React Native也将在下一个稳定发布版本中支持Hooks。

视频指导

在React Conf 2018,Sophie Alpert 和 Dan Abramov 介绍来Hooks,接着Ryan Florence演示了怎样用它们重构APP。视频在这里(www.youtube.com/embed/dpw9EHDh2bM)。

没有破坏性更改

在我们继续之前,注意Hooks是:

  • 完全可选的。你可以在那些还没开发的组件中尝试Hooks。不过你要是不想用,大可不必学习它们;
  • 100%向后兼容。Hooks没有破坏性变更;
  • 即使可用。React v16.8.0版本就能用;

React可没有计划移除class。你可以在本页底部了解更多关于Hooke逐步被采用的相关策略信息。
Hooks也不会取代你当前的React概念。反之,对于你所熟知的概念:state、props,context,ref,声明周期这些东西,Hooks提供了一些更直接的API。正如我们将很快看到的,Hooks也提供了一种结合它们的强大手段。
假如你这就想开始学习Hooks,轻轻松松跳到下一讲去!继续阅读这一讲,你能了解到更多关于我们为什么要增加Hooks,以及我们怎样不重写我们的程序来开始使用它们。

动机

Hooks解决了一系列看似毫无联系的难题,这些难题我们在过去的五年里在编写和维护数以万计的组件时都遇到过。无论你是学习React,每天使用React,亦或是使用其他类似组件模型的框架,你都有可能意识到这些问题。

在组件间复用有状态的逻辑很难

React没有提供一种把可复用行为“依附”在组件上的方法。如果你使用了React一段时间,你可能熟悉比如渲染props和高阶组件这类模式试图解决这类问题。但这类模式需要你重新架构你的组件,这样很繁重而且让组件很难遵循。如果你用React DevTools去查看一个典型的React应用,就会发现一大堆组件被“provider”、“layer”、“consumers”、高阶组件、渲染props和其他抽象包裹的嵌套地狱。即使我们可以在DevTools中过滤这些东西,但这些问题还是指向更深的底层问题:React需要一个更好的原生途径来分享有状态逻辑。
通过Hooks,就可以从组件中提取出有状态的逻辑,这样它还能独立被测试和重用。Hooks可以使你不用改变组件层级就能复用有状态逻辑。这就把许多组件间或者在社区中分享hooks变得十分简单了。
我们将在后续章节“构建自定义组件”中讨论更多。

复杂组件变得难以理解

我们经常会维护那些起初简单,但是最终变成一堆无法管理的状态逻辑和副作用的组件。每一个声明周期方法通常包含了不相关的逻辑。比如说,在componentDidMount和componentDidUpdate中,组件发起数据请求。但是,这个相同的componentDidMount也可能包含了一些没有联系的逻辑,比如设置监听器,而这些又要在componentWillUnmount中被移除。相互联系的代码更改后被分开,但是毫无关联的代码却在同一个方法中。这就很容易导致bug和不一致。
在很多情况下无法将这些组件分解成更小的组件因为有状态的逻辑无处不在。测试它们也很难。这就是为什么许多人喜欢把React和独立的状态管理库结合使用。然而,这通常又导致了太多的抽象,需要你在不同文件中切换,同时组件复用也很难。
为了解决这些问题,Hooks能让你将组件拆分成基于相互关联的片段的更小函数(正如请求数据,设置订阅等),而不是强行的在生命周期方法中(把相关逻辑)分割开来。你也可能选择用reducer来管理组件的本地状态来变得更可预测。
我们将会讨论更多在后面章节“使用Effect Hooks”中。

Class使人和机器都感到迷惑

除了使代码复用和组织更加困难外,我们还发现class是学习React的巨大障碍。你得理解this在JavaScript中的工作机制,这和其他语言的机制很不一样。你得记得“bind”事件处理器。没有不稳定的语法建议,代码将十分冗长。人们很容易理解state,props,自顶向下数据流,却对class感到挣扎。函数组件和class组件的区别以及应什么时候来使用它们也让有经验的React开发者们争论不休。
此外,React也推出又5年了,并且我们也想在未来五年有相关性。就像Svelt,Angular,Glimmer和其他展示的那样,提前编译组件在未来有很大潜力。尤其假如不限制模版。近期,我们积累了些经验关于用Prepack打包组件,并有取得了些早期阶段的预期结果。然而,我们发现class组件可能会鼓励一些降低这些乐观预期的无意识的模式。class也在当今的一些工具中存在问题,比如,class不能很好的压缩,并且,它们让热加载变得行为古怪不可信赖。我们想增加一些API来保证代码更有希望停留在乐观的路上。
解决这些问题,Hooks让你使用更多React特性而不局限class。概念上讲,React组件也更接近函数。Hooks拥抱函数,但却没有牺牲React的实质精神。Hooks提供进入紧急逃生舱入口(?不理解)且不需要你学习复杂的函数或者交互式编程技术。

例子

“初见Hooks”是学习Hooks的好去处

逐步采用策略

TLDR(Too Long Didnot Read ,引申为总结):没有计划从React中移除class

我们指导React开发者关注把产品推向市场,没时间投入到每一个新发布的的API中。Hooks是非常新的,并且,在考虑学习和采用它之前,等待更多例子和教程是更好的。
我们也指导添加一个React的原生特性的门槛现在非常高。对于有兴趣的读者,我们已经准备了一些RFC的细节,这些细节深入到动机和更多细节,并提供了特有的设计决定和相关现有技术的额外视角。
重要的是,Hooks和现存代码同时工作,这样你能逐步的采用它们。没必要迁移到Hooks。我们不推荐任何“大规模重写”,尤其那些现有的,复杂的组件。“用Hooks来思考”会耗费极大的思维转化开销。我们的经验是,最好在新的不重要的组件开始实践Hooks,并确保你的团队用着舒服。在你浅尝Hooks之后,请随时给我们反馈,积极的或者消极的。
我们想让Hooks覆盖所有的class的使用场景,但是我们会继续支持class组件,在可预见的未来。在Facebook,我们用class写了数以万计的组件,我们也完全没计划重写它们。反之,我们开始在新代码中使用Hooks和class组件一起工作。

高频问题

我们准备了Hooks FAQ这一讲来回答最常见的关于Hooks的问题

下一步

通过这一讲,你已经有了一个粗略的想法关于Hooks解决了什么问题,但是很多细节可能不清楚。别急!让我们到下一讲,开始通过例子学习Hooks把