React的生命周期与运用

目次

  • 1.react组件的两种建立写法

  • 2.组件的生命周期在差别状况下的实行递次

  • 3.组件各生命周期的运用

1.react组件的两种建立写法

第一种ES5写法,React.createClass

React.createClass({
    getDefaultProps() {
        return {
            key1:value1
        }
    },
    getInitialState() {
        return {
            state1:state1
        }
    }
});

第二种是ES6写法,继续React.Component类

export default class Test1 extends React.Component {
    constructor (props) {
        super(props);
        this.state = {
            state1: state1
        }
    }
    static defaultProps = {
        data: 2,
    };
    static propTypes = {
        optionsData: React.PropTypes.array,
        onSelect: React.PropTypes.func,
        selectedOption: React.PropTypes.object,
        topStyle: React.PropTypes.any,
        placeholder: React.PropTypes.string
    }
 
}

getDefaultProps、getInitialState是在createClass时挪用的要领,而在继续component类时,getDefaultProps要领对应给类增加静态属性 defaultProps ,getInitialState 对应在类的组织函数中设置 state属性

2.组件的生命周期在差别状况下的实行递次

组件首次装载(first-Mount):

  • getDefaultProps() →

  • getInitialState() →

  • componentWillMount() →

  • render() →

  • componentDidMount()

卸载组件时(Unmount):componentWillUnmount()

当从新装载组件时(Re-Mount):

  • getInitialState()→

  • componentWillMount()→

  • render() →

  • componentDidMount(),

  • 但并不实行 getDefaultProps; defaultProps是放在组件类上的static属性

当再次衬着组件时(Re-Render),此时按递次实行

  • componentWillReceiveProps(nextProps )(组件接收到新的props才会挪用,只是转变state时不挪用)→

  • shouldComponentUpdate(组件接收到新的props才会挪用,只是转变state时不挪用)→

  • componentWillUpdate→

  • render →

  • componentDidUpdate。

零丁挪用setState的从新衬着

  • componentWillUpdate→

  • render →

  • componentDidUpdate

1、在单页运用中,用react-router的history做页面跳转时,是将当前route的一切组件卸载,再跳转返来时是从新装载组件,而不是首次装载。

2、在运用react-native的Navigator时,每次push新页面的时刻是首次加载,旧页面没有卸载,在pop新页面的时刻,新页面会卸载 挪用Unmount,旧页面是从新衬着

  • componentWillReceiveProps→

  • componentWillUpdate→

  • render →

  • componentDidUpdate。
    ,不是从新装载,也没有从新衬着的shouldComponentUpdate掌握,所以pop返来一定从新衬着。

3、组件在内存中装载过一次以后,组件的defaultProps就初始化了,以后装载就不会从新设置。

4、父组件的render都邑引发子组件的从新衬着。

5、 不能在componentWillUpdate ,render和componentDidUpdate 中挪用setState

3.组件各生命周期的运用

3.1 getDefaultProps要领 或许 defaultProps 对象

  • 只在组件类建立的时刻挪用一次,以后会被缓存起来。

  • defaultProps在组件实例之前建立,实例间同享。

  • 会和父组件设置的props举行兼并。

3.2 getInitialState要领或constructor的state属性

项目中会把组件用到的state初始化在这里

constructor (props) {
    super(props);
    this.state = {
        poi: null,
        activeTabId: null,
        cartCount: Shopcart.size(),
        domSize:{
            headerHeight: 100,
            bannerHeight: 200,
            categoryTabHeight: 100,
        },
        hiddenBanner: false //是不是隐蔽banner
    };

}

3.3 componentWillMount()

组件首次render之前挪用,假如在此要领中挪用setState,render将感知到更新后的state,而且只实行这一次render,能够在此要领中fetch数据,不须要dom操纵的数据猎取。

3.4 render()

组件衬着的要领,是组件唯一的必需完成的要领,在该要领中,我们能够经由过程props和state衬着差别的组件。返回null或许false代表不衬着任何东西。

render () {
    return (
        <header className="header-wrapper">
            <div className="header header-normal">
                {this.renderLeftComponent()}
                <span>{this.props.title || '美团商超'}</span>
                {this.renderRightComponent()}
            </div>
        </header>
    );
}

3.5 componentDidMount()

组件装载后挪用的要领,由于该要领挪用的时刻,组件已装载,而且该要领不在render的轮回当中,平常在该要领中做一些fetch数据或许转变state的要领。
还能够经由过程ReactDOM.findDOMNode(_this.refs.wrapper) 来猎取DOM节点 举行操纵。

componentDidMount() {
    this.mounted = true;
    if(this.props.poi){
        this.fetchCategoryTabs(this.props.poi.poiId);
    }
    if(!this.isCalculate) {
        this.calculateWidth(); 
    }
}

3.6 componentWillReceiveProps(nextProps)

在组件接收到新的 props 的时刻挪用。在初始化衬着的时刻,该要领不会挪用。能够在该要领中推断,当props变化时,是不是再去从新fetch数据,setState。

componentWillReceiveProps (nextProps) {
    if(nextProps.poi &&(nextProps.poi != this.props.poi)) {
        this.fetchBannerList(nextProps.poi.poiId);
    }
}

3.7 shouldComponentUpdate(nextProps, nextState)

在接收到新的props或许state变化时,被挪用,该要领在初始化衬着和forceUpdate的时刻不会被挪用。

 默许返回true,假如返回false,则render不会实行。能够在这个要领中来阻挠不必要的render,由于偶然是由于父组件的render引发的子组件不必要的render。
shouldComponentUpdate(nextProps, nextState) {
    const isStateChanged = Object.keys(nextState).some(key=> {
        return nextState[key] !== this.state[key]
    });
    const isPropsChanged = Object.keys(nextProps).some(key=> {
        return nextProps[key] !== this.props[key]
    });
    return isStateChanged || isPropsChanged
}

3.8 componentWillUpdate(nextProps, nextState)

在接收到新的 props 或许 state 之前马上挪用。在初始化衬着的时刻该要领不会被挪用。运用该要领做一些更新之前的准备工作。你不能在刚要领中运用 this.setState()。假如须要更新 state 来相应某个 prop 的转变,请运用 componentWillReceiveProps。 项目中运用不多。

3.9 componentDidUpdate

在组件的更新已同步到 DOM 中以后马上被挪用。该要领不会在初始化衬着的时刻挪用。运用该要领能够在组件更新以后操纵 DOM 元素。

有些操纵能够须要操纵DOM元素,而且在第一次componentDidMount时还没有到达前提,所以须要在componentDidUpdate时再做操纵,然则componentDidUpdate在render的轮回函数中,
所以须要设置变量做掌握。

下面例子中 this.isCalculate 就是推断是不是计算过的变量。

componentDidMount() {
    this.mounted = true;
    if(this.props.poi){
        this.fetchCategoryTabs(this.props.poi.poiId);
    }
    if(!this.isCalculate) {
        this.calculateWidth(); 
    }
}
componentDidUpdate () {
    if(!this.isCalculate) {
        this.calculateWidth(); 
    }
}
calculateWidth () {
    if(this.isCalculate) {
        return;
    }
    let tablist = this.state.categoryTabs;
    if(tablist.length == 0) {
        return;
    }
    let tabsDOM = this.refs.tablist,
        childrensDOM = tabsDOM.childNodes,
        container = this.refs.tabcontainer,
        wrapper = this.refs.wrapper,
    // 横向转动宽度
        scrollwidth = 5;
    for(let i=0; i<childrensDOM.length; i++){
        let childDOM = childrensDOM[i];
        scrollwidth += childDOM.clientWidth + parseInt(childDOM.style.marginRight);
    }
    scrollwidth = Math.max(tabsDOM.clientWidth,scrollwidth);
    this.setState({tabsWidth: scrollwidth + 'px'});
     
    this.props.setCategoryTabHeight(wrapper.offsetHeight);
    this.isCalculate = true;
}

3.10 componentWillUnmount

在组件从 DOM 中移除的时刻马上被挪用。在该要领中实行任何必要的清算,比方无效的定时器,或许消灭在 componentDidMount 中建立的 DOM 元素。
能够纪录组件的mount状况,在 componentDidMount 中设置this.mounted = true 。 在componentWillUnmount 中设置 this.mounted = false。

    原文作者:传播正能量
    原文地址: https://segmentfault.com/a/1190000007329757
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞