Browse Source

新旧生命周期对比

pull/74/head
jingxun 2 years ago
parent
commit
9c9c0cce82
  1. 116
      day17/note/lesson44_new_old_life.md

116
day17/note/lesson44_new_old_life.md

@ -16,7 +16,123 @@
以上就是上节课所提到的三大最常用的生命周期钩子。接下来我们开始对新版生命周期的学习
## 新版本`react`
在我们将新版的`react`生命周期之前我们也还是有准备工作要做的,我们现在用的`react`是不是 16 版本的啊?这个是旧版本,那么新版本生命周期肯定得用新版本`react`才能用,那么我们就要在代码中引入新版本的`react`。
当然这一步我就不不给大家展示了,大家自行下载新版本的依赖包。
## 生命周期流程图(新)
![](https://file.lynchow.com/react%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F(%E6%96%B0).png)
## 案例回顾
这个流程图看着和旧版本的差别好像很大,咱们先不着急看。咱先来快速过一下之前我们的案例:
```jsx
class Count extends React.Component {
{/* 构造器方法 */}
constructor(props) {...}
{/* 其他生命周期钩子 */}
componentWillMount() {...}
componentDidMount() {...}
componentWillUnmount() {...}
shouldComponentUpdate() {...}
componentWillUpdate() {...}
componentDidUpdate() {...}
{/* render方法 */}
render() {...}
{/* 事件回调 */}
add = () => {...}
unmount = () => {...}
}
class CountSub extends React.Component {
state = {count: 10};
render() {...}
clear = () => {...};
}
class Test extends React.Component {
componentWillReceiveProps(){...}
componentWillMount(){...}
render() {...}
}
```
大致框架就是这个样子,我们在里面写了构造器,构造器里面初始化了`state,render`方法中则展示了`state`的值,然后点击`Add`按钮使数字加一,点击`Unmount`按钮则卸载整个组件。
然后我又写了两个租价来测是父子组件之间的更新。
好了以上就是我们之前的案例。
## 新版本生命周期测试
上面我们都已经把之前的案例过了一遍了,那么接下来我们是不是就应该来写新版本生命周期了呢?咱先别着急。咱们先看看新版本生命周期里能不能用旧版本生命周期的钩子我们来用上面的代码来测试一下,看一下结果:
![image-20211231100604087](https://file.lynchow.com/image-20211231100604087.png)
页面成功渲染了,我们电解按钮之后页面也更新了,但是控制台中好像有很多警告,但是我们该执行的钩子是不是好像都已经执行了啊?
说一句玩笑话,程序员不在乎警告。那么我先问一句,在新版本中能不能使用旧版本的生命周期钩子?从上面的结果来看是不是完全没有问题的,只不过会有警告提示而已。我们从警告上面也看出来了,说得很清楚:`componentWillMount`和`componentWillUpdate`钩子都被重命名了,而且不被推荐使用了。
但是这两个钩子改叫什么了呢?下面也有,就是在前面加了一个`UNSAFE`前缀。而且后面也说了,从`react 18`开始就只能加上`UNSAFE`前缀才能使用。
但是我现在这边先说一个结论:在旧版生命周期钩子中,所有包含`will`的钩子,到了新版本中除了`componentWillUnmount`以外,官方都推荐加上`UNSAFE`前缀。
## `UNSAFE`前缀
但是加了`UNSAFE`这是不是就代表着这两个钩子已经不安全了呢?其实这并不是不安全,那么是什么意思呢?我们来看一下警告中提供的链接吧:
![image-20211231101805081](https://file.lynchow.com/image-20211231101805081.png)
官方的文档给出了解释。因为`react`在设计一个新的功能叫异步渲染,官网预测这几个钩子在未来版本中被滥用的话可能会导致`bug`尤其是在异步渲染中。
所以说`UNSAFE`在这里指的并不是安全性的问题。
## 新版本钩子弃用
当然我们上面说了那么多,其实简单一句话可以说明,新版本的生命周期弃用了旧版本中的三个钩子,分别是:
- `componentWillMount`
- `componentWillUpdate`
- `componentWillReceiveProps`
## 新旧版本生命周期对比
可能有人要说我们这是不是就算是学完了新版本的生命周期?这才哪到哪啊?我们到现在都还没有看新版本的流程图呢。
那么接下来我们来跟着流程图吧新旧版本来做一个对比:
挂载时,新旧版本的生命周期都会先调用`constructor`方法。但是紧接着,区别就出来了,新版本弃用了旧版本中的`componentWillMount`,那么新版本就不会再去调用`componentWillMount`方法了,但是新版本多了一个`getDerivedStateFromProps`钩子,然后两个版本都到了`render`方法,这个是没有区别的。当`render`方法执行完毕,完成挂载之后,旧版本就直接调用`componentDidMount`钩子了。
那么新版本呢?大家都看到新版本的流程图里多了一个环节叫`React`更新`DOM`和`refs`。是不是新版本比旧版本多了一个环节呢?其实这个环节在旧版本中也有,而且也是在同样地位置。只是旧版本的流程图中并没有画出来。所以说新版本在执行完`render`之后也是执行了`componentDidMount`钩子,和旧版本没有什么区别。
那么卸载时呢,新版本的图把卸载时单独画了一下,但是其实和旧版本没有什么区别,就是当你卸载的时候会在卸载前调用`componentWillUnmount`钩子。
那么更新时呢,旧版本中更新有三个入口,父组件重新`render`,`setState`,`forceUpdate`。再来看新版本,也是三个入口,`new props`,`setState`,`forceUpdate`。新旧版本的这三个入口其实是不是完全一样的啊?父组件重新`render`的话,那不就会传入新`props`嘛。
但是旧版本这三个入口会分别对应三个不同的起点,但是再看新版本,这三个入口的起点都是`getDerivedStateFromProps`钩子。而且也废弃掉了`componentWillReceiveProps`钩子。然后就和旧版本一样,经过`shouldComponentUpdate`,当然`forceUpdate`是直接跳过这一步的。然后,旧版本到达了`componentWillUpdate`钩子,但是这个钩子在新版本中可是已经废弃了。所以新版本中就没有这一步了。
再然后都到达`render`方法,更新完组件之后,又出现了一个不同点。旧版本在更新完组件之后会调用`componentDidUpdate`钩子,但是新版本在调用`componentDidUpdate`之前还调用了一个我们之前也一直没有见过的`getSnapshotBeforeUpdate`钩子。然后再调用`componentDidUpdate`钩子。
以上就是新旧版本生命周期的对比。
当然上面说到的新增的两个钩子我们这节课先不去了解,只是知道有这么个东西就行了。我们在接下来的课程中再来详细学习。
## 总结
- 新版本生命周期可以使用旧版本的钩子
- 新版本中废弃了三个旧版本中的钩子,使用这三个钩子要加`UNSAFE`前缀
- `componentWillMount`
- `componentWillUpdate`
- `componentWillReceiveProps`
- 新版本中新增了两个钩子
- `getDerivedStateFromProps`
- `getSnapshotBeforeUpdate`
Loading…
Cancel
Save