felix-cao / Blog

A little progress a day makes you a big success!
31 stars 4 forks source link

React 组件的生命周期函数(Lifecycle Methods) #147

Open felix-cao opened 5 years ago

felix-cao commented 5 years ago

一、生命周期函数概念

React 是一个用于构建 (building) 用户界面 (User Interfaces) 的 JavaScript 库,这是 React 官方React 的一个简短的俏皮话简介 (one-liner introduction)。即:

A JavaScript library for building user interfaces

用户界面可以想象成一个多功能的游乐场 (multi-option playground), 用户可以在这里做很多很多事,而 React 库可以帮助我们创建这个游乐场。

用户与软件的交互是通过在用户界面组件 (UI Component) 上进行的点击、悬停、按键等各种事件 (events) 完成的, 所有的用户界面组件都会在浏览器中诞生,并在某个时间点消失。

我们每天在经历着各种事件,每一个事件都有一些事情发生、更新和死亡,应用程序的 UI 组件如同自然界的一样(树、食物)通过各种形式的输入而诞生、生长,并且在某个时间点会死亡。

如果我们能够知道这些生命周期事件,我们便可以控制它们的整个流程,以便优化控制使其利益最大化。多么 Happy 的一件事啊!

👍 React 组件的生命周期函数指的是React 的组件生命周期的不同阶段调用的各种方法

二、生命周期函数的调整

2018年的3月份,React 官方发布了 v16.3 版本,在这次更新中,新引入了两个生命周期函数:

同时,也有在未来 v17.0 版本中即将被移除的三个生命周期函数:

三个将被移除的生命周期函数都加了前缀 UNSAFE_; React 团队的这一做法使得生命周期函数变得更加简洁。

让我们来看一下 React 这次生命周期函数调整之前图示:

三、生命周期及其8个生命周期函数

React v16.3 之后,任何一个 React 组件都会经历下面三个阶段:

下图展示了 React 组件生命周期的不同阶段及调用的函数

红线圈起来的三个生命周期函数是在未来 v17.0 版本中即将被移除的。

3.1、constructor

组件创建后第一个调用的函数,在整个生命周期中仅调用一次。 在这个函数中需要注意的:

class App extends React.Component
constructor(props) {
  super(props);
  this.state = {}
}

3.2、static getDerivedStateFromProps

这个方法是在 constructor 函数之后调用,返回一个对象用于更新组件的 state,也就是说这个方法主要用来保证 stateprop 数据更新同步。这个函数需要注意的是:

static getDerivedStateFromProps(props, state) {
  if (state.value !== props.value) {
      return {
        derivedValue: deriveValueFromProps(props),
        mirroredProp: props.value
      }
     }
  // 当返回 null 时,没有state更新变化
  return null;
}

// getDerivedStateFromProps 被调用过后,state的值应该时这样的:

//   {
//    derivedValue: someValue,
//    mirrordValue: newPropValue
//   }

3.3、render

每一个 React 组件都必须有一个 render 函数

3.4、componentDidMount

组件已经挂载,在 render 之后执行,只执行一次。一般在这里进行数据请求操作。

3.5、shouldComponentUpdate(nextProps,nextState)

除了render 函数,shouldComponentUpdate 可能是 React 组件生命周期中最重要的一个函数了。 说 render 函数重要,是因为 render 函数决定了该渲染什么,而说 shouldComponentUpdate 函数重要,是因为它决定了一个组件什么时候不需要渲染。

React生命周期函数中,只有rendershouldComponentUpdate两个函数要求有返回结果。render 函数的返回结果将用于构造 DOM 对象,而 shouldComponentUpdate 函数返回一个布尔值,告诉 React 库这个组件在这次更新过程中是否要继续。

在更新过程中,React 库首先调用 shouldComponentUpdate 函数,如果这个函数返回 true,那就会继续更新过程,接下来调用 render 函数;反之,如果得到一个 false,那就立刻停止更新过程,也就不会引发后续的渲染了。如果使用得当,就能够大大提高 React 组件的性能,虽然 React的渲染性能已经很不错了,但是,不管渲染有多快,如果发现没必要重新渲染,那就干脆不用渲染就好了,速度会更快。

3.6、getSnapshotBeforeUpdate

新的 getSnapshotBeforeUpdate 生命周期在更新之前被调用(例如,在DOM被更新之前)。此生命周期的返回值将作为第三个参数传递给 componentDidUpdate。 (这个生命周期不是经常需要的,但可以用于在恢复期间手动保存滚动位置的情况。)

componentDidUpdate 一起,这个新的生命周期将覆盖旧版 componentWillUpdate 的所有用例。

3.7、componentDidUpdate

这个生命周期函数很少使用,componentDidUpdate() 紧跟在更新发生后调用。对于初次的渲染,该方法并不会调用。如果 shouldComponentUpdate 返回的值为 false,这个函数就不会被调用。

当组件被更新之后,使用此方法作为操作DOM的一次机会。这也是一个适合发送请求的地方,只要你对比了当前属性和前一次属性(例如,如果属性没有改变那么请求也就没必要了)。

3.8、componentWillMount

该方法在组件销毁之前调用,可以在该方法里处理任何必要的清理工作,例如解绑定时器,取消网络请求,清理任何在componentDidMount环节创建的订阅。

Reference