【React 全家桶】React生命周期的新旧对比

一、介绍生命周期

需求:
1、文字从透明度为1变为0,反复执行这个动画
2、点击按钮将页面清空(卸载组件)

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>生命周期</title>
</head>

<body>
    <!-- 创建一个容器 -->
    <div id="test"></div>
    <!-- 引入react核心库 -->
    <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <!-- 引入react-dom,用于支持react操作dom -->
    <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
    <!-- 引入bable,将jsx转化为js -->
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>

    <script type="text/babel">
        class Demo extends React.Component {
      
      
            state = {
      
       opacity: 1 }
            //卸载组件
            death = () => {
      
      
                ReactDOM.unmountComponentAtNode(document.querySelector('#test'))
            }
            //组件挂载完成
            componentDidMount() {
      
      
                this.timer = setInterval(() => {
      
      
                    let {
      
       opacity } = this.state;
                    opacity -= 0.1;
                    if (opacity <= 0) opacity = 1;
                    this.setState({
      
       opacity });
                }, 200);
            }
            //组件将要卸载
            componentWillUnmount() {
      
      
                //清除定时器,否则会一直执行计时器
                clearInterval(this.timer)
            }
            //组件渲染的时候,状态更新之后
            render() {
      
      
                console.log('render')
                return (
                    <div>
                        <h2 style={
      
      {
      
       opacity: this.state.opacity }}>React?</h2>
                        <button onClick={
      
      this.death}>卸载</button>
                    </div>
                )
            }
        }
        ReactDOM.render(<Demo />, document.querySelector('#test'))
    </script>
</body>

</html>

在这里插入图片描述

二、生命周期(旧)

在这里插入图片描述
16x版本的生命周期顺序:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>生命周期</title>
</head>

<body>
    <!-- 创建一个容器 -->
    <div id="test"></div>
    <!-- 引入react核心库 -->
    <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <!-- 引入react-dom,用于支持react操作dom -->
    <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
    <!-- 引入bable,将jsx转化为js -->
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>

    <script type="text/babel">
        class Demo extends React.Component {
      
      
            constructor(props) {
      
      
                console.log('最开始:constructor')
                super(props)
                this.state = {
      
       Count: 0 }
            }
            //组件将要挂载
            componentWillMount() {
      
      
                console.log('组件将要挂载,componentWillMount')
            }
            //组件渲染的时候,状态更新之后
            render() {
      
      
                console.log('组件渲染的时候,状态更新之后:render')
                const {
      
       Count } = this.state;
                return (
                    <div>
                        <h2>求和为{
      
      Count}</h2>
                        <button onClick={
      
      this.add}>加一</button>
                        <button onClick={
      
      this.death}>卸载组件</button>
                        <button onClick={
      
      this.force}>强制更新</button>
                    </div>
                )
            }
            //组件挂载完成
            componentDidMount() {
      
      
                console.log('组件挂载完成:componentDidMount')
            }
            //控制组件更新的“阀门”(如果不写默认是true)
            shouldComponentUpdate() {
      
      
                console.log('控制组件更新的“阀门”:shouldComponentUpdate')
                //返回值是true的才能继续往下一个生命周期走
                return true
            }
            //组件将要更新
            componentWillUpdate() {
      
      
                console.log('组件将要更新:componentWillUpdate')
            }

            //组件更新完成
            componentDidUpdate() {
      
      
                console.log('组件更新完成:componentDidUpdate')
            }
            //组件将要卸载
            componentWillUnmount() {
      
      
                console.log('组件将要卸载:componentWillUnmount')
            }
            //卸载组件
            death = () => {
      
      
                ReactDOM.unmountComponentAtNode(document.querySelector('#test'))
            }
            //强制更新 - 不更改setState的数据
            force = () => {
      
      
                this.forceUpdate()
            }
            add = () => {
      
      
                let {
      
       Count } = this.state;
                Count++;
                this.setState({
      
       Count })
            }
        }

        ReactDOM.render(<Demo />, document.querySelector('#test'))
    </script>
</body>

</html>

子父组件的生命周期(componentWillReceiveProps)

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>生命周期(子父组件)</title>
</head>

<body>
    <!-- 创建一个容器 -->
    <div id="test"></div>
    <!-- 引入react核心库 -->
    <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <!-- 引入react-dom,用于支持react操作dom -->
    <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
    <!-- 引入bable,将jsx转化为js -->
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>

    <script type="text/babel">
        //定义父组件
        class Parent extends React.Component {
      
      
            state = {
      
       name: '奔驰' }
            change = () => {
      
      
                this.setState({
      
       name: '宝马' })
            }
            render() {
      
      
                console.log('父组件渲染的时候,状态更新之后:render')
                return (
                    <div>
                        <div>parent</div>
                        <button onClick={
      
      this.change}>切换</button>
                        <Child name={
      
      this.state.name} />
                    </div>
                )
            }
        }
        //定义子组件
        class Child extends React.Component {
      
      
            //组件将要接收到Props
            componentWillReceiveProps() {
      
      
                console.log('子组件将要接收父组件的Props:componentWillReceiveProps')
            }
            //组件挂载完成
            componentDidMount() {
      
      
                console.log('子组件挂载完成:componentDidMount')
            }
            render() {
      
      
                console.log('子组件渲染的时候,状态更新之后:render')
                return (
                    <div>
                        <div>child:{
      
      this.props.name}</div>
                    </div>
                )
            }
            //控制组件更新的“阀门”(如果不写默认是true)
            shouldComponentUpdate() {
      
      
                console.log('控制子组件更新的“阀门”:shouldComponentUpdate')
                //返回值是true的才能继续往下一个生命周期走
                return true
            }
            //组件将要更新
            componentWillUpdate() {
      
      
                console.log('子组件将要更新:componentWillUpdate')
            }

            //组件更新完成
            componentDidUpdate() {
      
      
                console.log('子组件更新完成:componentDidUpdate')
            }
            //组件将要卸载
            componentWillUnmount() {
      
      
                console.log('子组件将要卸载:componentWillUnmount')
            }
        }
        ReactDOM.render(<Parent />, document.querySelector('#test'))
    </script>
</body>

</html>

三、生命周期(新)

在这里插入图片描述
17x版本的生命周期顺序:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>17版本生命周期</title>
</head>

<body>
    <!-- 创建一个容器 -->
    <div id="test"></div>
    <!-- 引入react核心库 -->
    <script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
    <!-- 引入react-dom,用于支持react操作dom -->
    <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
    <!-- 引入bable,将jsx转化为js -->
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>


    <script type="text/babel">
        /* 新的生命周期和旧的生命周期相比,它废弃了3个钩子:componentWillMount、componentWillReceiveProps、componentWillUpdate。
            同时又提出两个新的钩子:getDerivedStateFromProps、getSnapshotBeforeUpdate。 
        */
       /*
        1.初始化阶段:由ReactDOM。render()触发---初次渲染
            1.consructor()
            2.getDerivedStateFormProps
            3.render()
            4.componentDidMount() ===> 常用
            一般在这个钩子中做一些初始化的事情,比如;开启定时器、发送网络请求、订阅消息
        2.更新阶段:由组件内部this.setState()或父组件重新render触发
            1.getDerivedStateFromProps
            2.shouldComponentUpdate()
            3.render()
            4.getSnapshotBeforeUpdate
            5.componentDidUpdate()
        3.卸载组件:由ReactDOM.unmountComponentAtNode()触发
            1.componentWillUnmount() ===>常用
            一般在这个钩子中做一些收尾的事情,比如关闭定时器、取消订阅消息
       */
        class Demo extends React.Component {
      
      
            constructor(props) {
      
      
                console.log('最开始:constructor')
                super(props)
                this.state = {
      
       count: 0 }
            }
            //组件将要挂载
            // UNSAFE_componentWillMount() {
      
      
            //     console.log('组件将要挂载(17版本能用,但是会警告),componentWillMount')
            // }

            //在调用 render 方法之前调用,并且在初始挂载及后续更新时都会被调用
            //若state的值任何时候都取决于props,可以使用getDerivedStateFromProps
            static getDerivedStateFromProps(props, state) {
      
      
                console.log('getDerivedStateFromProps', props)
                return null
            }

            //更新之前获取快照
            getSnapshotBeforeUpdate() {
      
      
                console.log('getSnapshotBeforeUpdate')
                return '快照值'
            }
            //组件渲染的时候,状态更新之后
            render() {
      
      
                console.log('组件渲染的时候,状态更新之后:render')
                const {
      
       count } = this.state;
                return (
                    <div>
                        <h2>求和为{
      
      count}</h2>
                        <button onClick={
      
      this.add}>加一</button>
                        <button onClick={
      
      this.death}>卸载组件</button>
                        <button onClick={
      
      this.force}>强制更新</button>
                    </div>
                )
            }
            //组件挂载完成
            componentDidMount() {
      
      
                console.log('组件挂载完成:componentDidMount')
            }
            //控制组件更新的“阀门”(如果不写默认是true)
            shouldComponentUpdate() {
      
      
                console.log('控制组件更新的“阀门”:shouldComponentUpdate')
                //返回值是true的才能继续往下一个生命周期走
                return true
            }
            //组件将要更新(写了getDerivedStateFromProps UNSAFE_就不能存在)
            // UNSAFE_componentWillUpdate() {
      
      
            //     console.log('组件将要更新(17版本能用,但是会警告):componentWillUpdate')
            // }

            //组件更新完成(快照值传到这里了)
            componentDidUpdate(perProps,preState,snapValue) {
      
      
                console.log('组件更新完成:componentDidUpdate',perProps,preState,snapValue)
            }
            //组件将要卸载
            componentWillUnmount() {
      
      
                console.log('组件将要卸载:componentWillUnmount')
            }
            //卸载组件
            death = () => {
      
      
                ReactDOM.unmountComponentAtNode(document.querySelector('#test'))
            }
            //强制更新 - 不更改setState的数据
            force = () => {
      
      
                this.forceUpdate()
            }
            add = () => {
      
      
                let {
      
       count } = this.state;
                count++;
                this.setState({
      
       count })
            }
        }

        ReactDOM.render(<Demo count={
      
      199} />, document.querySelector('#test'))
    </script>
</body>

</html>

1.初始化阶段:由ReactDOM。render()触发—初次渲染
    1.consructor()
    2.getDerivedStateFormProps
    3.render()
    4.componentDidMount() =>常用
    一般在这个钩子中做一些初始化的事情,比如;开启定时器、发送网络请求、订阅消息
2.更新阶段:由组件内部this.setState()或父组件重新render触发
    1.getDerivedStateFromProps
    2.shouldComponentUpdate()
    3.render()
    4.getSnapshotBeforeUpdate
    5.componentDidUpdate()
3.卸载组件:由ReactDOM.unmountComponentAtNode()触发
    1.componentWillUnmount() =>常用
    一般在这个钩子中做一些收尾的事情,比如关闭定时器、取消订阅消息

新增的两个钩子:

  1. getDerivedStateFromProps
//在调用 render 方法之前调用,并且在初始挂载及后续更新时都会被调用
//若state的值任何时候都取决于props,可以使用getDerivedStateFromProps
static getDerivedStateFromProps(props, state) {
    
    
     console.log('getDerivedStateFromProps', props)
     return null
}
  1. getSnapshotBeforeUpdate
//更新之前获取快照
getSnapshotBeforeUpdate() {
    
    
    console.log('getSnapshotBeforeUpdate')
    return '快照值'
}

四、新旧的区别

回答方式:新的生命周期和旧的生命周期相比,它废弃了3个钩子:componentWillMount、componentWillReceiveProps、componentWillUpdate,同时又提出两个新的钩子:getDerivedStateFromProps、getSnapshotBeforeUpdate。

五、重要的钩子(常用)

1.render:初始化渲染或更新渲染调用
2.componentDidMount:开启监听,发送ajax请求
3.componentWillUnmount:做一些收尾的工作,如:清除定时器

六、即将废弃的钩子

1.componentWillMount
2.componentWillReceiveProps
3.componentWillUpdate

现在使用会出现警告,需要加上UNSAFE_前缀才能使用,以后可能会直接废弃。

以上就是React 中生命周期的内容,请大家关注《React 全家桶》专栏。
我会将自己平时项目中常见的问题以及笔试面试的知识在CSDN与大家分享,一起进步,加油。

猜你喜欢

转载自blog.csdn.net/weixin_46318413/article/details/122512537