美文网首页前端开发那些事儿
【React】4.0 组件的生命周期

【React】4.0 组件的生命周期

作者: bobokaka | 来源:发表于2021-06-08 08:38 被阅读0次
1.0 生命周期的理解
  1. 组件从创建到死亡它会经历一些特定的阶段。
  2. React组件中包含一系列勾子函数(生命周期回调函数), 会在特定的时刻调用。
  3. 我们在定义组件时,会在特定的生命周期回调函数中,做特定的工作。

首先创建如下代码:

<!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>hello_react</title>
  </head>
  <!-- 1.0 准备容器 -->
  <div id="test"></div>
  <!-- 2.0引入react核心库 -->
  <script type="text/javascript" src="../js/react.development.js"></script>
  <!-- 3.0 引入react-dom,用于支持react操作DOM -->
  <script type="text/javascript" src="../js/react-dom.development.js"></script>
  <!-- 引入babel ,用于将jsx转为js -->
  <script type="text/javascript" src="../js/babel.min.js"></script>
  <!-- 引入prop-types,用于对组件标签属性进行限制 -->
    <script type="text/javascript" src="../js/prop-types.js"></script>

    <script type="text/babel">
        //创建组件
        class Life extends React.Component{
            //初始化渲染、状态更新之后
            render(){
                console.log('render');
                return(
                    <div>
                        <h2>React学不会怎么办?</h2>
                        <button>不活了</button>
                    </div>
                )
            }
        }
        //渲染组件
        ReactDOM.render(<Life/>,document.getElementById('test'))
    </script>
  </body>
</html>

image.png

目的:让上面文本自动透明变不透明,渐变切换。

当Clock组件第一次被渲染到DOM中的时候,魏骑设置一个定时器。这种在React中被称之为“挂载(mount)”,所以从DOM中删除Clock组件时,清除计时器,在React中被称之为“卸载(unmount)”。

    <script type="text/babel">
        //创建组件
        class Life extends React.Component{

            death=()=>{
                        //卸载组件
                        ReactDOM.unmountComponentAtNode(document.getElementById('test'))
            }

            //初始化渲染、状态更新之后
            render(){
                console.log('render');
                return(
                    <div>
                        <h2>React学不会怎么办?</h2>
                        <button onClick={this.death}>不活了</button>
                    </div>
                )
            }
        }
        //渲染组件
        ReactDOM.render(<Life/>,document.getElementById('test'))
    </script>

运行,点击按钮就是卸载,刷新页面自然就出现挂载行为。

透明度发生变化,自然是状态中的数据在驱动。

    <script type="text/babel">
        //创建组件
        class Life extends React.Component{
        //状态:透明度
        state = {opacity:1}

            death=()=>{
                        //卸载组件
                        ReactDOM.unmountComponentAtNode(document.getElementById('test'))
            }

            //初始化渲染、状态更新之后
            render(){
                console.log('render');
                return(
                    <div>
                        <h2 style={{opacity:this.state.opacity}}>React学不会怎么办?</h2>
                        <button onClick={this.death}>不活了</button>
                    </div>
                )
            }
        }
        //渲染组件
        ReactDOM.render(<Life/>,document.getElementById('test'))
    </script>

接下来需要透明度不断地发生变化。

    <script type="text/babel">
        //创建组件
        //生命周期回调函数 <=> 生命周期钩子函数 <=> 生命周期函数 <=> 生命周期钩子
        class Life extends React.Component{

            state = {opacity:1}

            death = ()=>{
                //卸载组件
                ReactDOM.unmountComponentAtNode(document.getElementById('test'))
            }

            //组件挂完毕
            componentDidMount(){
                console.log('componentDidMount');
                this.timer = setInterval(() => {
                    //获取原状态
                    let {opacity} = this.state
                    //减小0.1
                    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(<Life/>,document.getElementById('test'))
    </script>
2.0 旧的生命周期
image.png
2.1 挂载

生命周期在代码中出现的顺序和执行顺序无关。

    <script type="text/babel">
        //创建组件
        class Count extends React.Component{
        //初始化状态
        state={count:0}

                    //加1按钮的回调
        add = ()=>{
                        //获取原状态
                        const {count} = this.state
                        //更新状态
                        this.setState({count:count+1})
        }
        render(){
                //获取原状态
                const {count} = this.state
                return(
                    <div>
                        <h2>当前求和为:{count}</h2>
                        <button onClick={this.add}>点我+1</button>
                    </div>
                )
            }
            }
        
        //渲染组件
        ReactDOM.render(<Count/>,document.getElementById('test'))
    </script>

按图来 直接上测试代码:


    <script type="text/babel">
        //创建组件
        class Count extends React.Component{
        //构造器
        constructor(props){
            console.log('Count---constructor');
            super(props)
            //初始化状态
            this.state = {count:0}
        }

                    //加1按钮的回调
        add = ()=>{
                        //获取原状态
                        const {count} = this.state
                        //更新状态
                        this.setState({count:count+1})
        }

        
        //组件将要挂载的钩子
            componentWillMount(){
                console.log('Count---componentWillMount');
            }

            //组件挂载完毕的钩子
            componentDidMount(){
                console.log('Count---componentDidMount');
            }

        render(){
                console.log('Count---render');
                //获取原状态
                const {count} = this.state
                return(
                    <div>
                        <h2>当前求和为:{count}</h2>
                        <button onClick={this.add}>点我+1</button>
                    </div>
                )
            }
            }
        
        //渲染组件
        ReactDOM.render(<Count/>,document.getElementById('test'))
    </script>

(一般构造器写在最前面)


image.png
2.2 卸载
    <script type="text/babel">
        //创建组件
        class Count extends React.Component{
        //构造器
        constructor(props){
            console.log('Count---constructor');
            super(props)
            //初始化状态
            this.state = {count:0}
        }

                    //加1按钮的回调
        add = ()=>{
                        //获取原状态
                        const {count} = this.state
                        //更新状态
                        this.setState({count:count+1})
        }

        //卸载组件按钮的回调
        death = ()=>{
            ReactDOM.unmountComponentAtNode(document.getElementById('test'))
        }

        //组件将要挂载的钩子
        componentWillMount(){
            console.log('Count---componentWillMount');
        }

        //组件挂载完毕的钩子
        componentDidMount(){
            console.log('Count---componentDidMount');
        }
        
        //组件将要卸载的钩子
        componentWillUnmount(){
            console.log('Count---componentWillUnmount');
        }

        render(){
                console.log('Count---render');
                //获取原状态
                const {count} = this.state
                return(
                    <div>
                        <h2>当前求和为:{count}</h2>
                        <button onClick={this.add}>点我+1</button>
                        <button onClick={this.death}>卸载组件</button>
                    </div>
                )
        }
    }
        
        //渲染组件
        ReactDOM.render(<Count/>,document.getElementById('test'))
    </script>

点击“卸载组件”:


image.png
2.3 更新

更新可以分为3种情况:


image.png

其中最正常的情况,是第二种。

2.4 setState涉及的更新

    <script type="text/babel">
        //创建组件
        class Count extends React.Component{
        //构造器
        constructor(props){
            console.log('Count---constructor');
            super(props)
            //初始化状态
            this.state = {count:0}
        }

                    //加1按钮的回调
        add = ()=>{
                        //获取原状态
                        const {count} = this.state
                        //更新状态
                        this.setState({count:count+1})
        }

        //卸载组件按钮的回调
        death = ()=>{
            ReactDOM.unmountComponentAtNode(document.getElementById('test'))
        }

        //组件将要挂载的钩子
        componentWillMount(){
            console.log('Count---componentWillMount');
        }

        //组件挂载完毕的钩子
        componentDidMount(){
            console.log('Count---componentDidMount');
        }
        
        //组件将要卸载的钩子
        componentWillUnmount(){
            console.log('Count---componentWillUnmount');
        }

        //控制组件更新的“阀门”:组件是否应该被更新:true:false
        shouldComponentUpdate(){
            console.log('Count---shouldComponentUpdate');
            return true
        }

        render(){
                console.log('Count---render');
                //获取原状态
                const {count} = this.state
                return(
                    <div>
                        <h2>当前求和为:{count}</h2>
                        <button onClick={this.add}>点我+1</button>
                        <button onClick={this.death}>卸载组件</button>
                    </div>
                )
        }
    }
        
        //渲染组件
        ReactDOM.render(<Count/>,document.getElementById('test'))
    </script>
image.png
shouldComponentUpdate必须有返回值,如果不自定义写,React也会给一个默认的勾子函数,并永远返回true

    <script type="text/babel">
        //创建组件
        class Count extends React.Component{
        //构造器
        constructor(props){
            console.log('Count---constructor');
            super(props)
            //初始化状态
            this.state = {count:0}
        }

                    //加1按钮的回调
        add = ()=>{
                        //获取原状态
                        const {count} = this.state
                        //更新状态
                        this.setState({count:count+1})
        }

        //卸载组件按钮的回调
        death = ()=>{
            ReactDOM.unmountComponentAtNode(document.getElementById('test'))
        }

        //组件将要挂载的钩子
        componentWillMount(){
            console.log('Count---componentWillMount');
        }

        //组件挂载完毕的钩子
        componentDidMount(){
            console.log('Count---componentDidMount');
        }
        
        //组件将要卸载的钩子
        componentWillUnmount(){
            console.log('Count---componentWillUnmount');
        }

        //控制组件更新的“阀门”:组件是否应该被更新:true:false
        shouldComponentUpdate(){
            console.log('Count---shouldComponentUpdate');
            return true
        }

        //组件将要更新的钩子
        componentWillUpdate(){
            console.log('Count---componentWillUpdate');
        }

        //组件更新完毕的钩子
        componentDidUpdate(){
            console.log('Count---componentDidUpdate');
        }

        render(){
                console.log('Count---render');
                //获取原状态
                const {count} = this.state
                return(
                    <div>
                        <h2>当前求和为:{count}</h2>
                        <button onClick={this.add}>点我+1</button>
                        <button onClick={this.death}>卸载组件</button>
                    </div>
                )
        }
    }
        
        //渲染组件
        ReactDOM.render(<Count/>,document.getElementById('test'))
    </script>
image.png
2.5 forceUpdate()涉及的更新

force:军队、武装、强制。这里指的是强制更新。
只比正常流程少一步绕过阀门。

    <script type="text/babel">
        //创建组件
        class Count extends React.Component{
        //构造器
        constructor(props){
            console.log('Count---constructor');
            super(props)
            //初始化状态
            this.state = {count:0}
        }

                    //加1按钮的回调
        add = ()=>{
                        //获取原状态
                        const {count} = this.state
                        //更新状态
                        this.setState({count:count+1})
        }

        //强制更新按钮的回调
        force = ()=>{
            this.forceUpdate()
        } 
        //卸载组件按钮的回调
        death = ()=>{
            ReactDOM.unmountComponentAtNode(document.getElementById('test'))
        }

        //组件将要挂载的钩子
        componentWillMount(){
            console.log('Count---componentWillMount');
        }

        //组件挂载完毕的钩子
        componentDidMount(){
            console.log('Count---componentDidMount');
        }
        
        //组件将要卸载的钩子
        componentWillUnmount(){
            console.log('Count---componentWillUnmount');
        }

        //控制组件更新的“阀门”:组件是否应该被更新:true:false
        shouldComponentUpdate(){
            console.log('Count---shouldComponentUpdate');
            return true
        }

        //组件将要更新的钩子
        componentWillUpdate(){
            console.log('Count---componentWillUpdate');
        }

        //组件更新完毕的钩子
        componentDidUpdate(){
            console.log('Count---componentDidUpdate');
        }

        render(){
                console.log('Count---render');
                //获取原状态
                const {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>
                )
        }
    }
        
        //渲染组件
        ReactDOM.render(<Count/>,document.getElementById('test'))
    </script>
image.png
2.6 父组件render涉及的更新

将Count组件折叠,创建两个组件A、B, 让AB形成父子关系。

    <script type="text/babel">
        //创建组件
        class Count extends React.Component{...

        //父组件A
        class A extends React.Component{

            render(){
                return(
                    <div>
                        <div>我是A组件</div>
                        <B />
                    </div>
                )
            }
        }
        
        //子组件B
        class B extends React.Component{
            render(){
                return(
                    <div>我是B组件</div>
                )
            }
        }
        
        //渲染组件
        ReactDOM.render(<A/>,document.getElementById('test'))
    </script>
image.png

如下需求:A组件更改信息,由B组件展示信息。

    <script type="text/babel">
        //创建组件
        class Count extends React.Component{...

    //父组件A
        class A extends React.Component{
            //初始化状态
            state = {carName:'奔驰'}

            changeCar = ()=>{
                this.setState({carName:'奥拓'})
            }

            render(){
                return(
                    <div>
                        <div>我是A组件</div>
                        <button onClick={this.changeCar}>换车</button>
                        <B carName={this.state.carName}/>
                    </div>
                )
            }
        }
        
        //子组件B
        class B extends React.Component{
            render(){
                return(
                    <div>我是B组件,接收到的车是:{this.props.carName}</div>
                )
            }
        }
        
        //渲染组件
        ReactDOM.render(<A/>,document.getElementById('test'))
    </script>
image.png
    <script type="text/babel">
        //创建组件
        class Count extends React.Component{...

    //父组件A
        class A extends React.Component{
            //初始化状态
            state = {carName:'奔驰'}

            changeCar = ()=>{
                this.setState({carName:'奥拓'})
            }

            render(){
                return(
                    <div>
                        <div>我是A组件</div>
                        <button onClick={this.changeCar}>换车</button>
                        <B carName={this.state.carName}/>
                    </div>
                )
            }
        }
        
        //子组件B
        class B extends React.Component{

            //组件将要接收新的props的钩子
            componentWillReceiveProps(props){
                console.log('B---componentWillReceiveProps',props);
            }
            
            //控制组件更新的“阀门”
            shouldComponentUpdate(){
                console.log('B---shouldComponentUpdate');
                return true
            }
            //组件将要更新的钩子
            componentWillUpdate(){
                console.log('B---componentWillUpdate');
            }
            
            //组件更新完毕的钩子
            componentDidUpdate(){
                console.log('B---componentDidUpdate');
            }

            render(){
                console.log('B---render');
                return(
                    <div>我是B组件,接收到的车是:{this.props.carName}</div>
                )
            }
        }
        
        //渲染组件
        ReactDOM.render(<A/>,document.getElementById('test'))
    </script>

这里有一个问题,componentWillReceiveProps方法执行第一次不执行。


image.png

完成代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>2_react生命周期(旧)</title>
</head>
<body>
    <!-- 准备好一个“容器” -->
    <div id="test"></div>
    
    <!-- 引入react核心库 -->
    <script type="text/javascript" src="../js/react.development.js"></script>
    <!-- 引入react-dom,用于支持react操作DOM -->
    <script type="text/javascript" src="../js/react-dom.development.js"></script>
    <!-- 引入babel,用于将jsx转为js -->
    <script type="text/javascript" src="../js/babel.min.js"></script>

    <script type="text/babel">
        /* 
                1. 初始化阶段: 由ReactDOM.render()触发---初次渲染
                                    1.  constructor()
                                    2.  componentWillMount()
                                    3.  render()
                                    4.  componentDidMount() =====> 常用
                                                    一般在这个钩子中做一些初始化的事,例如:开启定时器、发送网络请求、订阅消息
                2. 更新阶段: 由组件内部this.setSate()或父组件render触发
                                    1.  shouldComponentUpdate()
                                    2.  componentWillUpdate()
                                    3.  render() =====> 必须使用的一个
                                    4.  componentDidUpdate()
                3. 卸载组件: 由ReactDOM.unmountComponentAtNode()触发
                                    1.  componentWillUnmount()  =====> 常用
                                                    一般在这个钩子中做一些收尾的事,例如:关闭定时器、取消订阅消息
        */
        //创建组件
        class Count extends React.Component{

            //构造器
            constructor(props){
                console.log('Count---constructor');
                super(props)
                //初始化状态
                this.state = {count:0}
            }

            //加1按钮的回调
            add = ()=>{
                //获取原状态
                const {count} = this.state
                //更新状态
                this.setState({count:count+1})
            }

            //卸载组件按钮的回调
            death = ()=>{
                ReactDOM.unmountComponentAtNode(document.getElementById('test'))
            }

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

            //组件将要挂载的钩子
            componentWillMount(){
                console.log('Count---componentWillMount');
            }

            //组件挂载完毕的钩子
            componentDidMount(){
                console.log('Count---componentDidMount');
            }

            //组件将要卸载的钩子
            componentWillUnmount(){
                console.log('Count---componentWillUnmount');
            }

            //控制组件更新的“阀门”:组件是否应该被更新
            shouldComponentUpdate(){
                console.log('Count---shouldComponentUpdate');
                return true
            }

            //组件将要更新的钩子
            componentWillUpdate(){
                console.log('Count---componentWillUpdate');
            }

            //组件更新完毕的钩子
            componentDidUpdate(){
                console.log('Count---componentDidUpdate');
            }

            render(){
                console.log('Count---render');
                const {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>
                )
            }
        }
        
        //父组件A
        class A extends React.Component{
            //初始化状态
            state = {carName:'奔驰'}

            changeCar = ()=>{
                this.setState({carName:'奥拓'})
            }

            render(){
                return(
                    <div>
                        <div>我是A组件</div>
                        <button onClick={this.changeCar}>换车</button>
                        <B carName={this.state.carName}/>
                    </div>
                )
            }
        }
        
        //子组件B
        class B extends React.Component{
            //组件将要接收新的props的钩子
            componentWillReceiveProps(props){
                console.log('B---componentWillReceiveProps',props);
            }

            //控制组件更新的“阀门”
            shouldComponentUpdate(){
                console.log('B---shouldComponentUpdate');
                return true
            }
            //组件将要更新的钩子
            componentWillUpdate(){
                console.log('B---componentWillUpdate');
            }

            //组件更新完毕的钩子
            componentDidUpdate(){
                console.log('B---componentDidUpdate');
            }

            render(){
                console.log('B---render');
                return(
                    <div>我是B组件,接收到的车是:{this.props.carName}</div>
                )
            }
        }
        
        //渲染组件
        ReactDOM.render(<Count/>,document.getElementById('test'))
    </script>
</body>
</html>
3.0 新的生命周期

增加了2个新的勾子函数,废弃了原来的3个勾子函数。


image.png

相关文章

  • React概念图

    React概念图 React组件生命周期概念图 参考文档:React入门教程 组件生命周期React:组件生命周期...

  • React 组件生命周期

    组件生命周期 参考阅读: component-lifecycle react组件生命周期过程说明 react 组件...

  • React总结

    [toc] 1.React组件生命周期 1.1 生命周期图 组件的生命周期的图如下: 具体可参考React 组件生...

  • 学习并实现react (4)

    实现生命周期 生命周期介绍 React 生命周期图 React 子组件在父组件下的生命周期流程 实现 compon...

  • react(最近搞了一套react项目的视频 全套 有需

    React 组件生命周期在本章节中我们将讨论 React 组件的生命周期。 组件的生命周期可分成三个状态: Mou...

  • Notes On React - Two

    React 的生命周期   React组件 的生命周期大致可分成四个状态:  - Mounting:装配-组件实例...

  • 006@React组件的生命周期.md

    006@React组件的生命周期.md React Native 是基于组件化开发。弄清楚组件的生命周期对于我们开...

  • React 生命周期

    React 生命周期 初始化周期 组件重新渲染生命周期 组件卸载生命周期

  • react组件的生命周期

    第三单元(react组件的生命周期) 课程目标 灵活掌握react组件的生命周期以及组件的活动过程。 能够灵活使用...

  • 四:React 进阶三 (生命周期)

    react(一):组件的生命周期 生命周期函数 在组件运行的某个时刻,会被自动执行的一些函数。 React生命周期...

网友评论

    本文标题:【React】4.0 组件的生命周期

    本文链接:https://www.haomeiwen.com/subject/phtncltx.html