了解 React 之组件的 10 大生命周期

一、生命周期是什么

React 组件的生命周期是一种钩子函数,其实也可以理解为是一种回调函数,是 React 组件在创建更新卸载的整个过程中对外暴露出的方法,然后 React 组件会根据方法的返回值来决定内部怎么运作。比如 shouldComponentUpdate 的返回值是 false,那么即便是调用了 this.setState() 方法,也不会重新渲染页面;反之,如果是 true,则会重新渲染页面,也就是重新执行一遍 render() 方法。

二、生命周期有哪些

React 组件的生命周期分为三个阶段,一共有10个生命周期函数:
1. 初始化阶段

  • getDefaultProps
  • getInitialState
  • componentWillMount
  • render
  • componentDidMount

2. 更新阶段

  • componentWillReceiveProps
  • shouldComponentUpdate
  • componentWillUpdate
  • render
  • componentDidUpdate

3. 卸载阶段

  • componentWillUnmount

三、生命周期详解

下面会讲解一下每个生命周期的用法,并附带案例。
1. 初始化阶段

  • getDefaultProps:初始化 props,可以用 defaultProps 代替。
  • getInitialState:初始化 state,一般写在 this.state = {} 中。

这两个生命周期函数都是定义在 createClass 方法中。用法如下:

    var App = React.createClass({
        getDefaultProps(){
            return{
                title:'首页'
            }
        },
        getInitialState(){
            return{
                data:'数据'
            }
        },
        render(){
            return <div>{this.props.title}{this.state.data}</div>
        }
    })
    ReactDOM.render(<App/>, document.getElementById('example'));

如果用 defaultProps 和 this.state 代替, 用法如下:

    class App extends React.Component {
        constructor(props){
            super(props);
            this.state = {
                data:'数据'
            }
        }
        render() {
            return (
                    <div>
                        <div>{this.props.title}{this.state.data}</div>
                    </div>
            )
        }
    };
    App.defaultProps  = {
      title:'首页'
    };
    ReactDOM.render(<App/>, document.getElementById('example'));
  • componentWillMount:准备创建虚拟 DOM。
  • render:虚拟组件渲染,挂载。
  • componentDidMount:虚拟组件已经挂载完成,可在此阶段更新 state,或者调用接口,处理监听事件。
    class App extends React.Component {
        constructor(props){
            super(props);
            this.state = {
                title:'我是主页'
            }
        }
        componentWillMount(){
        //如果在 constructor 构造函数中我想重写 state,就可以在这里进行,
        //但仅仅只是改变 state,不会渲染页面
            this.state = {
                title:'不,我是首页'
            }
        }      
        componentDidMount(){
        //在这里,我可以调取数据接口,
        //执行 this.setState 改变 state,并且重新渲染页面
        }
        render() {
            return <div>最终的title为:{this.state.title}</div>
        }
    };
    ReactDOM.render(<App/>, document.getElementById('example'));

2. 更新阶段

  • componentWillReceiveProps:父组件更新引发子组件更新时调用。
  • shouldComponentUpdate:布尔值,是否更新组件,用来做性能优化。
  • componentWillUpdate:组件刚开始更新的时候,还未重新渲染 DOM 时触发。
  • render:根据更新的 state 和 props 重新渲染页面。
  • componentDidUpdate:组件完成更新,DOM 渲染完成。
    class App extends React.Component {
        constructor(props){
            super(props);
            this.state = {
                isRender:true,
                toSonText:'给子组件的props为1'
            };
        }
        click(){
            this.setState({
                toSonText:'给子组件的props为2'
            })
        }
        render() {
            return <div onClick={()=>this.click()}><Index  message = {this.state.toSonText}/>点击我改变传给子组件的props</div>
        }
    };
    class Index extends React.Component {
        constructor(props){
            super(props);
            this.state = {
                title:'我是主页'
            }
        }
        componentWillReceiveProps(nextProps, nextContext){
            //当父组件更新时,我就会触发,并拿到最新的 props
            console.log(nextProps.message)
        }
        componentWillUpdate(){
            //state 更新时,我还可以在挂载前改变 state,但是不会重新渲染页面
            this.state.title = '不,我是首页'
        }
        componentDidUpdate(){
            //state 更新完成,我可以改变 state 并且渲染页面
            //可以在这里调取数据接口,执行 this.setState 改变 state 并渲染页面
        }
        render() {
            return <div><div>父组件传过来的 message 为:{this.props.message}</div><div>最终的title为:{this.state.title}</div></div>
        }
    };
    ReactDOM.render(<App/>, document.getElementById('example'));

3. 卸载阶段

  • componentWillUnmount:组件卸载时触发。在这个阶段可以消除一些定时器或事件。
    如下代码所示,点击父组件卸载掉子组件,并清掉定时器。
    class App extends React.Component {
        constructor(props){
            super(props);
            this.state = {
                isRender:true
            };
        }
        click(){
            this.setState({
                isRender:false
            })
        }
        render() {
            return <div onClick={()=>this.click()}>{this.state.isRender?<Index/>:null}<div>点击</div></div>
        }
    };
    class Index extends React.Component {
        constructor(props){
            super(props);
            this.state = {
                count:0
            }
        }
        componentDidMount(){
            this.timer = setInterval(()=>{
                this.setState({
                    count:++this.state.count
                })
            },1000)
        }
        componentWillUnmount(){
            clearInterval(this.timer);
        }
        render() {         
            return <div>{this.state.count}</div>
        }
    };
    ReactDOM.render(<App/>, document.getElementById('example'));

如果不清掉定时器,定时器仍在执行,但是组件已不再,所以会一直报错如下:
在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值