前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >小结React(一):组件的生命周期及执行顺序

小结React(一):组件的生命周期及执行顺序

原创
作者头像
前端林子
修改2019-04-13 19:41:19
4.4K0
修改2019-04-13 19:41:19
举报
文章被收录于专栏:前端技术总结前端技术总结

0.说明

本文作为React总结系列的第一篇文章,会总结组件的生命周期及执行顺序,涉及内容比较基础。在后面的系列文章中则会总结React Hooks等内容。

1.七个可选的生命周期

说明:

(1) componentWillMount()  仅在render()方法前被调用一次,如果在该方法中调用了setState方法去改变组件的状态值,那么调用render()后,将会直接看到改变过了的状态值,并且不论状态值怎么改变,componentWillMount()都不会再被调用。

(2) componentDidMount()  仅在render()方法后被立即调用一次,相对于父组件而言,该方法在子组件中会先被调用。如果需要使用一些JaveScript框架或者类似于setInterval()这样的方法,建议在该方法内使用。

(3) shouldComponentUpdate(object nextProps, object nextState)  在首次渲染调用render()方法时不会被调用,后面在接受到新的state或者props时,在render()方法前被调用。为防止一些潜在的bug,该方法默认总是返回true。如果确定state及props改变后不需要渲染组件,那么也可以指定返回false,需要注意的是,这样的结果会导致后面的render()、componentWillUpdate()、componentDidUpdate()都不会被调用。不过,React官方建议这个方法仅用来做优化性能,不要用这个方法来阻止渲染,因为可能会产生bug。

例如React内置的PureComponent的类,当我们的组件继承于它时,组件更新时就会默认先比较新旧属性和状态,从而决定组件是否更新。值得注意的是,PureComponent进行的是浅比较,所以组件状态或属性改变时,都需要返回一个新的对象或数组

(4)componentWillReceiveProps(object nextProps) 

在初始渲染调用render()方法时不会被调用,当接收到一个新的props时,该方法被调用。另外,如果改变一个状态的值,则会触发render()方法。因此可以在这个方法里调用setState()方法去改变一个状态的值,当该方法接收到新的props时,setState()就可以避免一次额外的render()了。

(5) componentWillUpdate(object nextProps, object nextState)  在初始渲染调用render()方法时不会被调用,当接收到新的props及state时,在render()方法之前被调用。

不要在此方法再去更新props 或者 state

(6) componentDidUpdate(object prevProps, object prevState)  在初始渲染调用render()方法时不会被调用,当组件更新被刷新到DOM之后被立即调用。

可以在这里访问,并修改 DOM

(7) componentWillUnmount()  在组件从DOM上卸载前被调用,在这个方法里面,主要是完成一些清除操作,比如说清除掉一些过时了的定时器等。

2.执行顺序

(1) getDefaultProps(),调用1次

(2) getInitialState(),调用1次

(3) componentWillMount(),调用1次

(3) render(),调用>=1次

(4) componentDidMount():调用1次

(5) componentWillReceiveProps(object nextProps),调用>=0次

(6) ShouldComponentUpdate(object nextProps, object nextState),调用>=0次

(7) componentWillUpdate(object nextProps, object nextState),调用>=0次

(8) render(),调用>=1次

(9) componentDidUpdate(object prevProps, object prevState),调用>=0次

(10) componentWillUnmount(),调用1次

3.实例

<!DOCTYPE html>

<html>

    <head>

        <script src="https://fb.me/react-15.2.0.js"></script>

        <script src="https://fb.me/react-dom-15.2.0.js"></script>

        <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>

    </head>

<body>

    <div id="app-container"></div>

    <script type="text/babel">
        var SubCounter = React.createClass({
            componentWillReceiveProps:function() {
                console.log('9、子组件将要接收到新属性');
            },

            shouldComponentUpdate:function(newProps, newState) {
                console.log('10、子组件是否需要更新');
                if (newProps.number < 5) return true;
                return false
            },

            componentWillUpdate:function() {
                console.log('11、子组件将要更新');
            },

            componentDidUpdate:function() {
                console.log('13、子组件更新完成');
            },

            componentWillUnmount:function() {
                console.log('14、子组件将卸载');
            },

            render:function() {
                console.log('12、子组件挂载中');
                return (
                        <p>{this.props.number}</p>
                )
            }
        });

        var Counter = React.createClass({
           
            getInitialState:function(){
                return(
                    this.state={
                        number:0
                    }
                )
            },

            componentWillMount:function(){
                console.log('3、父组件挂载之前');
            },

            componentDidMount:function(){
                console.log('5、父组件挂载完成');
            },

            shouldComponentUpdate:function(newProps, newState) {
                console.log('6、父组件是否需要更新');
                if (newState.number<15) return true;
                return false
            },

            componentWillUpdate:function() {
                console.log('7、父组件将要更新');
            },

            componentDidUpdate:function() {
                console.log('8、父组件更新完成');
            },

            handleClick : function(){
                this.setState({
                    number: this.state.number + 1
                })
            },
            render:function() {
                console.log('4、render(父组件挂载)');
                return (
                    <div>
                        <p>{this.state.number}</p>
                        <button onClick={this.handleClick}>+</button>
                        {this.state.number<10?<SubCounter number={this.state.number}/>:null}
                    </div>
                )
            }
        });        

        ReactDOM.render(<Counter />, document.getElementById('app-container'));

    </script>

</body>

</html>

结果:

4. 其他

(1)constructor(props){}

constructor(props){
    super(props);
    this.state = {}
}

在React组件挂载之前,会调用它的构造函数。在为 React.Component 子类实现构造函数时,应先调用 super(),并传入参数props。构造函数中,可以通过this.state来初始化组件内部的state(注意这里不是setState()方法来设置state),还可以为事件处理函数绑定实例:

constructor(props) {
    super(props);
    // 注意:不要在这里调用 this.setState()
    this.state = { counter: 0 };
    this.handleClick = this.handleClick.bind(this);
}

(2)defaultProps

用于为class组件添加默认的props,示例:

class sayHello extends React.Component {
    render() {
        return (
            <h1>Hello,{this.props.name}</h1>
        );
    }
}

sayHello.defaultProps = {
    name:"Peter"
}

(3)propTypes 进行类型检测

PropTypes 提供一系列验证器,可用于确保组件接收到的prop值是有效的。当传入的 prop 值类型不正确时,JavaScript 控制台将会显示警告。示例:

import PropTypes from 'prop-types';
class sayHello extends React.Component {
    render() {
        return (
            <h1>Hello,{this.props.name}</h1>
        );
    }
}

sayHello.propTypes = {
    name: PropTypes.string
};

(4) render()  对于一个组件而言,render()方法是必须的,通常在这个方法里面都会返回一个元素(如:<div></div>),但同样也可以返回false或null,这意味着没有任何东西需要渲染。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 0.说明
  • 1.七个可选的生命周期
  • 2.执行顺序
  • 3.实例
  • 4. 其他
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档