美文网首页前端开发那些事儿
【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】4.0 组件的生命周期

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