** Hooks在React 16.8版本中正式被引入。它可以让你在不用写class的条件下使用state以及其他的React特性。**
const fn = () => {
const [count, setCount] = useState(0)
return (
<div>
<p>{count}</p>
<button onClick={() => setCount(count++)}>
点击我
</button>
</div>
)
}
这个useState的新方法是我们第一个要学的Hook,但这个例子仅仅是开胃菜。如果觉得这个例子没有意义暂时先不要担心。
React 16.8.0是支持Hooks的第一个发行版本。当升级的时候不要忘了把包含React DOM的整个包都升级。React Native将在下一个稳定发行版本中支持Hooks。
Hooks不包含突破性变化
在继续之前,我们应该知道Hooks是
- 完全可选的。你可以在完全不重写既有代码的情况下尝试使用Hooks。如果你暂时不考虑Hooks,也不需要学习和使用它。
- 100%向后兼容。Hooks不包含任何突破性变化。
- 目前已经可用了。在React 16.8.0中已经被引入。
没有计划把class从React中移除。
Hooks不会影响到你对React概念的任何理解。相反,Hooks对你已知的React概念比如props,state,context,refs以及生命周期回调提供了更直接的API。稍后我们会演示。同时Hooks提供了结合这些概念的强大方法。
创建Hooks的动力
Hooks解决了过去五年中我们在编写和维护数以万计的组件时所遇到的问题。无论你目前是正在学习React,还是已经日常使用它,或者更喜爱其他相似的组件框架,你都会遇到这些问题:
在组件之间复用有状态的逻辑很困难。
React没有提供一种可复用的把行为附在组件上(比如连接到一个store上)的方法。如果你对React略有经验,你可能对render props和高阶组件模式有所感知。但是这些模式需要你在使用的时候重新组织组件,这可能使得代码笨重并难以维护。如果你在React DevTools里查看React应用,你会发现一种"wrapper地狱"的现象——组件被provider,consumer,高阶组件等重重包裹。这些都指向了一个更深层次的问题——React需要一个共享有状态逻辑的原生能力。
通过Hooks,你可以把有状态逻辑从一个组件里抽取出来,从而它可以被复用以及单独测试。Hooks使得你可以在不更改组件层级的条件下复用原有状态逻辑。这样在多个组件之间以及社区之间共享Hooks就很容易了。
复杂组件变得难以理解
我们经常发现一开始组件总是简单并容易理解,但随之衍生出各种无法掌控的有状态逻辑以及副作用,难以维护。每一个生命周期回调方法都包含了一堆无关联的逻辑。比如,组件可能在componentDidMount和componentDidUpdate里去获取数据,但componentDidMound里还可能包含了一些建立监听的不相关的逻辑,同样在componentWillUnMount里也执行了清理动作。相互关联的代码被拆分到不同的地方,而不关联的代码又被结合到同一个方法里。最终很容易引入bug和不一致性。
很多场景下不太可能把这些组件拆分得更细,因为有状态逻辑遍布各处,同时要进行测试也很麻烦。这是许多人喜欢使用独立状态管理库的原因之一。但往往会引入太多的抽象,需要你在不同的文件之间跳来跳去,复用组件就更困难了。
Hooks允许你在关联的内容的基础上(比如建立监听或者获取数据)把一个组件拆成多个更小的方法,而不是在生命周期方法里糅合不同的逻辑代码。你也可以通过一个reducer来管理组件的内部state,使得它具备更高的可预见性。
Class会引起困惑
我们发现class语法不仅使得代码复用和组织困难,还是学习React的一个巨大障碍。你必须理解this关键词在JavaScript里如何工作,你还必须在事件处理方法中绑定this,没有可靠的语法提示,代码十分冗长。开发者尽管能很好理解prosp,state,以及自顶向下的数据流动,但还是对class难以驾驭。在React里何时使用function组件还是class组件在有经验的React开发者中也引起巨大的争议。
渐进策略
没有从React中移除class的计划
我们知道React开发者聚焦于交付产品,没空去看每一个新发布的API。Hooks很新,在决定学习引入之前最好等待更多的案例和教程。
我们也理解在React增加原生的特性门槛很高。对于有好奇心的读者,我们准备了这篇来深入更多的细节以及提供额外的设计决策上的洞察。
关键是,Hooks能和现有代码无缝连接工作,使得你能逐步引入使用。
版权归原作者 前端e站 所有, 如有侵权,请联系我们删除。