React组件生命周期新旧对比

106 阅读1分钟

React旧版生命周期

1.组件从创建到死亡它会经历一些特定的阶段
2.React组件中包含一系列的钩子函数(生命周期回调函数),会在特定时刻调用
3.我们在定义组件时,会在特定的生命周期回调函数中,做特定的工作
4.render(),被调用1+n次,1是页面初次渲染,n是页面更新的次数

在这里插入图片描述

  1. 初始化阶段:由ReactDOM.render()触发——初次渲染

    • constructor()
    • componentWillMount()
    • render()
    • componentDidMount()
  2. 更新阶段:由组件内部this.setState()或父组件重新触发render()

    • shouldComponentUpdate();
    • componentWillUpdate();
    • render();
    • componentDidUpdate();
  3. 卸载组件:由ReactDOM.unmountComponentAtNode()触发
    + componentWillUnmount()

最常用的三个钩子是componentDidMount() ,一般用这个钩子,做初始化的事,例如开启定时器,发送网络请求,订阅信息
componentWillUnmount(),一般在这个钩子中做一些收尾的事,例如:关闭定时器,取消订阅信息
render:初始化渲染或更新渲染调用

即将废弃的三个钩子函数:

  1. componentWillMount 2. componentWillReceiveProps 3. componentWillUpdate
    现在使用会出现警告,下一个大版本需要加上UNSAFE_前缀才能使用,以后可能会被彻底废弃,不建议使用。
<!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>Document</title>
</head>
<body>
    <!-- 创建一个容器 -->
    <div id="test"></div>

    <!-- 引入React核心库 -->
    <script src="./js/react.development.js"></script>
    <!-- 引入React-dom使用React操作dom -->
    <script src="./js/react-dom.development.js"></script>
    <!-- 引入babel将jsx转为js -->
    <script src="./js/babel.min.js"></script>

    <script type="text/babel">
        class Count extends React.Component{
            constructor(props){
                super(props);
                console.log('Count_constructor');
            };

            render(){
                console.log('Count_render');
                return(
                    <div>
                        <h1>React组件生命周期,三个将废弃,增加两个</h1>
                        <button onClick={this.death}>移除组件</button>
                    </div>
                )
            }

            death = ()=>{
                ReactDOM.unmountComponentAtNode(document.getElementById('test'));
            }

            // 组件将要挂载时触发的钩子函数
            componentWillMount(){
                console.log('Count_componentWillMount');
            };
            // 组件挂载完成触发的钩子函数
            componentDidMount(){
                console.log('Count_componentDidMount');
            }
            // 组件将要卸载时触发的钩子函数
           componentWillUnmount(){
               console.log('Count_componentWillUnmout');
           }

        }

        // 渲染组件
        ReactDOM.render(<Count />,document.getElementById('test'));
    </script>
</body>
</html>

在这里插入图片描述

<!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>Document</title>
</head>
<body>
    <!-- 创建一个容器 -->
    <div id="test"></div>

    <!-- 引入React核心库 -->
    <script src="./js/react.development.js"></script>
    <!-- 引入React-dom使用React操作dom -->
    <script src="./js/react-dom.development.js"></script>
    <!-- 引入babel将jsx转为js -->
    <script src="./js/babel.min.js"></script>

    <script type="text/babel">
        class Count extends React.Component{
            constructor(props){
                super(props);
                console.log('Count_constructor');
            };
            state = {opacity:1};

            render(){
                console.log('Count_render');
                return(
                    <div>
                        <h1 style={{opacity:this.state.opacity}}>React组件生命周期,三个将废弃,增加两个</h1>
                        <button onClick={this.death}>移除组件</button>
                    </div>
                )
            }

            death = ()=>{
                ReactDOM.unmountComponentAtNode(document.getElementById('test'));
            }

            // 组件将要挂载时触发的钩子函数
            componentWillMount(){
                console.log('Count_componentWillMount');
              
            };
            // 组件挂载完成触发的钩子函数
            componentDidMount(){
                console.log('Count_componentDidMount');
             this.timer =   setInterval(()=>{
                    let {opacity} = this.state;
                    opacity -=0.2;
                    if(opacity<=0){
                        opacity = 1;
                    }
                    this.setState({opacity:opacity});
                },200)
            }
            // 组件将要卸载时触发的钩子函数
           componentWillUnmount(){
               console.log('Count_componentWillUnmout');
               
           }

        }

        // 渲染组件
        ReactDOM.render(<Count />,document.getElementById('test'));
    </script>
</body>
</html>

报错:
在这里插入图片描述
不能在组件移除后设置state,防止内存泄漏情况

在组件将要销毁时,要销毁定时器,因为定时器会修改state的值

<!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>Document</title>
</head>
<body>
    <!-- 创建一个容器 -->
    <div id="test"></div>

    <!-- 引入React核心库 -->
    <script src="./js/react.development.js"></script>
    <!-- 引入React-dom使用React操作dom -->
    <script src="./js/react-dom.development.js"></script>
    <!-- 引入babel将jsx转为js -->
    <script src="./js/babel.min.js"></script>

    <script type="text/babel">
        class Count extends React.Component{
            constructor(props){
                super(props);
                console.log('Count_constructor');
            };
            state = {opacity:1};

            render(){
                console.log('Count_render');
                return(
                    <div>
                        <h1 style={{opacity:this.state.opacity}}>React组件生命周期,三个将废弃,增加两个</h1>
                        <button onClick={this.death}>移除组件</button>
                    </div>
                )
            }

            death = ()=>{
                ReactDOM.unmountComponentAtNode(document.getElementById('test'));
            }

            // 组件将要挂载时触发的钩子函数
            componentWillMount(){
                console.log('Count_componentWillMount');
              
            };
            // 组件挂载完成触发的钩子函数
            componentDidMount(){
                console.log('Count_componentDidMount');
             this.timer =   setInterval(()=>{
                    let {opacity} = this.state;
                    opacity -=0.2;
                    if(opacity<=0){
                        opacity = 1;
                    }
                    this.setState({opacity:opacity});
                },200)
            }
            // 组件将要卸载时触发的钩子函数
           componentWillUnmount(){
               console.log('Count_componentWillUnmout');
            //   清除定时器
            clearInterval(this.timer);
           }

        }

        // 渲染组件
        ReactDOM.render(<Count />,document.getElementById('test'));
    </script>
</body>
</html>
更新后钩子函数的顺序
<!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>Document</title>
</head>
<body>
    <!-- 创建一个容器 -->
    <div id="test"></div>

    <!-- 引入React核心库 -->
    <script src="./js/react.development.js"></script>
    <!-- 引入React-dom使用React操作dom -->
    <script src="./js/react-dom.development.js"></script>
    <!-- 引入babel将jsx转为js -->
    <script src="./js/babel.min.js"></script>

    <script type="text/babel">
        class Count extends React.Component{
            constructor(props){
                super(props);
                console.log('Count_constructor');
            };
            state = {
                count:0
            };

            render(){
                const {count} = this.state;
                console.log('Count_render');
                return(
                    <div>
                        <h2>当前求和:{count}</h2>
                        <button onClick={this.add}>点我+1</button>
                        <button onClick={this.death}>卸载组件</button>
                        <button onClick={this.force}>不更新任何状态中的数据,强制更新一下</button>
                    </div>
                )
            }

            // 强制更新按钮的回调
            force = ()=>{
                this.forceUpdate();
            }

            add = ()=>{
                 let count = this.state.count;
                 count++;
                 this.setState({count:count});
            }

            death = ()=>{
                ReactDOM.unmountComponentAtNode(document.getElementById('test'));
            }

            // 组件将要挂载时触发的钩子函数
            componentWillMount(){
                console.log('Count_componentWillMount');
              
            };
            // 组件挂载完成触发的钩子函数
            componentDidMount(){
                console.log('Count_componentDidMount');
            }
            // 组件将要卸载时触发的钩子函数
           componentWillUnmount(){
               console.log('Count_componentWillUnmout');
           }

        //    控制组件更新的“阀门”
           shouldComponentUpdate(){
               console.log('shouldComponentUpdate');
               return true;
           }

        //  组件将要更新时触发的钩子函数
           componentWillUpdate(){
            console.log('Count_componentWillUpdate');
           }

           componentDidUpdate(){
               console.log('Count_componentDidUpdate');
           }

        }

        // 渲染组件
        ReactDOM.render(<Count />,document.getElementById('test'));
    </script>
</body>
</html>

强制更新时:不执行shouldComponentUpdate,
在这里插入图片描述
如果点击更新:
在这里插入图片描述

新的生命周期函数(生命周期钩子函数)

1.初始化阶段:由ReactDOM.render()触发——初次渲染
		a.constructor()
		b.getDerivedStateFromProps
		c.render()
		d.componentDidMount()
2.更新阶段:由组件内部this.setState()或父组件重新render触发
		a.getDerivedStateFromProps
		b.shouldComponentUpdate()
		c.render()
		d.getSnapshotBeforeUpdate
		e.componentDidUpdate()
3.卸载组件:有ReactDOM.unmountComponentAtNode()触发

<!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>Document</title>
</head>
<body>
    <!-- 创建一个组件 -->
    <div id="test"></div>

    <!-- 引入react核心库 -->
    <script src="./js/17.0.1/react.development.js"></script>
    <!-- 引入react-dom用于React操作dom -->
    <script src="./js/17.0.1/react-dom.development.js"></script>
    <!-- 引入babel -->
    <script src="./js/17.0.1/babel.min.js"></script>

    <script type="text/babel">
        class Count extends React.Component{
            constructor(props){
                super(props);
                console.log('Count_constructor');
            }

            state = {count:0};

            render(){
                console.log('Count_render');
                let {count} = this.state; 
                return(
                    <div>
                        <h2>当前的值:{count}</h2>
                        <button onClick={this.add}>+1</button>
                        <button onClick={this.death}>卸载组件</button>
                        <button onClick={this.force}>不更新任何状态中的数据,强制更新</button>
                    </div>
                )
            }
            add = ()=>{
                let {count} =this.state;
                count++;
                this.setState({count:count});
            }
            // 页面强制更新数据
            force = () =>{
                this.forceUpdate();
            } 
            death = ()=>{
                ReactDOM.unmountComponentAtNode(document.getElementById('test'));
            }
        
            // 若state的值任何时候都取决于props
            static getDerivedStateFromProps(props,state){
                    console.log('Count_getDerivedStateFromProps',props,state);
                    return null;
            }


            // // 组件将要挂载时的钩子函数
            // UNSAFE_componentWillMount(){
            //     console.log('Count_componentWillMount');
            // }


            // 组件挂载完成时的钩子函数
            componentDidMount(){
                console.log('Count_componentDidMount');
            }
            // 组件将要卸载的钩子函数
            componentWillUnmount(){
                console.log('Count_componentWillUnmount');
            }
            // 控制组件更新的“阀门”
            shouldComponentUpdate(){
                console.log('Count_shouldComponentUpdate');
                return true;
            }
            // 在更新之前获取快照
            getSnapshotBeforeUpdate(){
                console.log('Count_getSnapshotBeforeUpdate');
                return 'charmer';
            }
            componentDidUpdate(){
                console.log('componentDidUpdate');
            }
        }

        // 渲染组件
        ReactDOM.render(<Count props={100}/>,document.getElementById('test'));
    </script>
</body>
</html>