一、class 组件存在的问题
1-1 复杂组件变得难以理解
随着业务的增多,class组件会变得越来越复杂,比如 componentDidMount 中,可能就会包含大量的逻辑代码:包括网络请求、一些事件的监听(还需要在componentWillUnmount中移除),没有做到关注点分离,而对于这样的class组件实际上非常难以拆分:因为它们的逻辑往往混在一起,强行拆分反而会造成过度设计,增加代码的复杂度
1-2 复杂的this指向
在class组件中,必须搞清楚this的指向到底是谁,所以需要花很多的精力去处理this指向
1-3 组件状态难以复用
class组件一些功能和状态的复用,通常需要通过高阶组件或render props,比如的redux中connect或者 react-router 中的 withRouter ,这些高阶组件设计的目的就是为了状态的复用。或者类似于Provider、Consumer 来共享一些状态,但是多次使用Consumer时,代码就会存在很多嵌套,这些代码让我们不管是编写和设计上来说,都变得非常困难
二、hooks 函数组件的优点
2-1 关注点分离,代码可读性增强
在class组件中原本同一块功能的代码逻辑被拆分在了不同的生命周期函数中,使开发者不利于维护和迭代,通过 React Hooks 可以将功能代码聚合,方便阅读维护。例如,每个生命周期中常常会包含一些不相关的逻辑。一般我们都会在 componentDidMount 和 componentDidUpdate 中发送请求获取数据。但是同一个 componentDidMount 中可能也包含很多其它的逻辑,如设置事件监听,而之后需在 componentWillUnmount 中清除。相互关联且需要对照修改的代码被进行了拆分,而完全不相关的代码却在同一个方法中组合在一起。如此很容易产生 bug,并且导致逻辑不一致
2-1 组件树层级变浅
在编写class组件的代码中,我们经常使用 HOC/render props 等方式来复用组件的状态,增强功能等,无疑增加了组件树层数及渲染,在 React DevTools 中观察过 React 应用,会发现由 provider,consumers,高阶组件,render props 等其他抽象层组成的组件会形成“嵌套地狱”。而在 React Hooks 中,这些功能都可以通过强大的自定义的 Hooks 来实现。