React Hooks开发实战
上QQ阅读APP看书,第一时间看更新

1.2 React Hooks生命周期

通过对前文的学习,我们对React Hooks有了初步的了解,对它的优缺点有了简单的认识,本节来介绍React Hooks的生命周期。只有对生命周期有了更好的理解,我们才能在实际开发中写出更加健壮的代码。

1.2.1 理解React Hooks生命周期

我们知道React Hooks是一种函数式的语法方式,每一个函数都是一个组件。普通的函数是不存在状态的,而生命周期存在的前提是有多状态,所以普通函数不存在生命周期。常规的React仅是一个render函数而已,但在引入Hooks之后就变得不同了,它能让组件在不使用Class的情况下拥有状态,所以就有了生命周期的概念。所谓的生命周期其实就是从变量声明到变量渲染完成的整个过程,这主要涉及如下几个函数。

□useState():声明变量函数。

□useEffect():渲染完成后执行函数。

□useLayoutEffect():渲染前执行函数。

综上所述,Hooks组件(使用了Hooks的函数组件)有生命周期,而函数组件(未使用Hooks的函数组件)是没有生命周期的。

1.2.2 函数式渲染与生命周期的关系

Class与Hooks的生命周期对应关系如表1-1所示。

表1-1 Class与Hooks的生命周期对应关系

下面我们用实际代码来介绍Class与Hooks的生命周期对应关系。先来看Class组件的钩子程序。

下面对上述代码中的各个钩子函数进行具体介绍。

□constructor:构造函数,如不初始化状态或者不进行函数绑定,可以不通过React组件来构造函数;通过在构造函数中初始化状态,接收来自父组件的props。

□getDerivedStateFromProps:React 16.8版本开始提供的静态方法,通过接收父组件props判断是否执行更新,返回null表示不更新。

□render:一个纯渲染函数,返回DOM、React组件、Fragment等。

□componentDidMount:组件挂载时调用,此时DOM已渲染,可以获取Canvas、SVG等操作,可以进行数据操作并获取接口数据。

□getSnapshotBeforeUpdate:组件内部函数,方法中,我们可以访问更新前的props和state。

□shouldComponentUpdate:用于返回组件是否重新渲染,当props或state发生变化时,它会在渲染之前被调用。如果返回true,则代表重新渲染组件;如果返回false,则代表不重新渲染组件。使用shouldComponentUpdate可以手动控制是否渲染组件,从而减少非必要渲染,提升组件性能。

□componentDidUpdate:组建更新后会被立即调用,但是首次渲染不会执行此方法,只有在二次更新的时候才会被触发。

□componentWillUnmount:组件卸载阶段执行的方法,组件销毁后会执行初始化相关的操作。

□getDerivedStateFromError和componentDidCatch:错误捕获日志。我们可以根据错误信息进行捕获,增强错误边界等组件与前端代码的兼容性。

接下来看看React Hooks钩子函数的代码实现。

下面对各个钩子函数进行具体介绍。

□useState:和Class的状态类似,只不过useState是独立管理组件变量的。

□useMemo:组件DOM节点,会进行一些计算,包括要渲染的DOM或数据,根据依赖参数进行更新。

□useEffect:React Hooks的组件生命周期其实就是通过钩子函数useEffect的不同用法实现的,传递不同的参数会导致不同的结果。

□useCallback:一个钩子函数,通过包裹普通函数进行性能优化。

1.2.3 函数式渲染的特点

React Hooks是一个函数,而函数的优势之一是可以保持单一性,只有理解了这一点才能写出好的函数式组件(Hooks组件)。

React中子组件受父组件传入的props控制,子组件不能直接修改props,也就是说这是一个单向数据流,这类似于纯函数,不能改变外部状态。所以我们在开发组件时,应当尽量将具有副作用的操作交给外部控制,这样的组件才是独立的,也具有高度的适应性。

函数式渲染具有以下显著特点。

□当给定相同输入(函数的参数)的时候,总是有相同的输出(返回值)。

□没有副作用。

□不依赖于函数外部状态。

□告别繁杂的this和难以记忆的生命周期。

□支持包装自己的Hooks(自定义Hooks),是纯命令式的API。

□可更好地完成状态之间的共享,解决了原来Class组件内部封装的问题,以及高阶组件和函数组件嵌套过深的问题。每个组件都有一个自己的状态,这个状态在该组件内可以共用。