React組件生命周期(舊)

一、概念

在組件創(chuàng)建、組件屬性更新、組件被銷毀的過程中,總是伴隨著各種各樣的函數(shù)執(zhí)行,這些在組件特定時期,被觸發(fā)執(zhí)行的函數(shù),統(tǒng)稱為組件的生命周期函數(shù)。

二、組件生命周期的三個階段

1、加載階段(Mounting):組件初始化時執(zhí)行,最顯著的特點是該階段的生命周期函數(shù)在組件的一輩子中只執(zhí)行一次
2、更新階段(Updating):屬性(props)和狀態(tài)(state)發(fā)生變化時執(zhí)行,根據(jù)組件pros和state的改變,有選擇性的觸發(fā)0次或多次
3、卸載階段(Unmounting):組件對象銷毀時執(zhí)行,一輩子只執(zhí)行一次

三、生命周期圖
React組件生命周期(舊).png
四、生命周期三個階段詳解

1、加載階段(Mounting,涉及6個鉤子函數(shù))
(1)constructor()——構造函數(shù),在加載時(創(chuàng)建組件時)調(diào)用一次,可以初始化state
(2)getDefaultProps()——設置默認的props,也可以用defaultProps設置組件的默認屬性
(3)getInitialState()——初始化state,可以直接在constuctor中定義this state
(4)componentWillMount()——組件加載之前調(diào)用,以后組件更新不調(diào)用,整個生命周期只調(diào)用一次,此時可以修改state,即調(diào)用setState,則本次的render函數(shù)可以看到更新后的state
(5)render()——react最重要的步驟,創(chuàng)建虛擬DOM,進行diff算法,更新DOM樹都在此階段進行,切忌不要再render里邊修改state
(6)componentDidMount()——組件渲染之后調(diào)用,只調(diào)用一次,此時子組件也掛載好了,可以使用refs

2、更新階段(Updating,涉及5個鉤子函數(shù))
(1)componentWillReceiveProps(nextProps)——組件加載時不調(diào)用,組件接收新的props時調(diào)用,父組件發(fā)生render的時候子組件就會調(diào)用(不管props有沒有更新,也不管父子組件之間有沒有數(shù)據(jù)交換)
(2)shouldComponentUpdate(nextProps, nextState)——組件接收到新的props或者state時調(diào)用,return true就會更新DOM(使用diff算法更新),return false可以阻止更新(不調(diào)用render),可以優(yōu)化渲染效率
(3)componentWillUpdate(nextProps, nextState)——組件加載時不調(diào)用,只有在組件將要更新時才調(diào)用,此時可以修改state
(4)render()——react最重要的步驟,創(chuàng)建虛擬DOM,進行diff算法,更新DOM樹都在此階段進行
(5)componentDidUpdate()——組件加載時不調(diào)用,組件更新完成后調(diào)用,除了首次render之后調(diào)用componentDidMount(),其他render結束之后都是調(diào)用componentDidUpdate()

3、卸載階段(Unmounting,涉及1個鉤子函數(shù))
(1)componentWillUnmount()——組件被卸載時調(diào)用,只調(diào)用一次,一般在componentDidMount里面注冊的事件需要在這里刪除

五、react組件更新方式:react中觸發(fā)render有4種方式

1、首次渲染initial render
2、調(diào)用this.setState(但并不是一次setState就會觸發(fā)一次render,React可能會合并操作,再一次性進行render)
3、父組件發(fā)生更新(一般就是props發(fā)生改變,但是就算props沒有改變或者父子組件之間沒有數(shù)據(jù)交換也會觸發(fā)render)
4、調(diào)用this.forceUpdate

React組件更新的4種方式.png
六、完整例子
class LifeCycle extends React.Component {
    constructor(props) {
        super(props);
        alert("Initial render");
        alert("constructor");
        this.state = {str: "hello"};
    }

    componentWillMount() {
        alert("componentWillMount");
    }

    componentDidMount() {
        alert("componentDidMount");
    }

    componentWillReceiveProps(nextProps) {
        alert("componentWillReceiveProps");
    }

    shouldComponentUpdate() {
        alert("shouldComponentUpdate");
        return true;        // 記得要返回true
    }

    componentWillUpdate() {
        alert("componentWillUpdate");
    }

    componentDidUpdate() {
        alert("componentDidUpdate");
    }

    componentWillUnmount() {
        alert("componentWillUnmount");
    }

    setTheState() {
        let s = "hello";
        if (this.state.str === s) {
            s = "HELLO";
        }
        this.setState({
            str: s
        });
    }

    forceItUpdate() {
        this.forceUpdate();
    }

    render() {
        alert("render");
        return(
            <div>
                <span>{"Props:"}<h2>{parseInt(this.props.num)}</h2></span>
                <br />
                <span>{"State:"}<h2>{this.state.str}</h2></span>
            </div>
        );
    }
}

class Container  extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            num: Math.random() * 100
        };
    }

    propsChange() {
        this.setState({
            num: Math.random() * 100
        });
    }

    setLifeCycleState() {
        this.refs.rLifeCycle.setTheState();
    }

    forceLifeCycleUpdate() {
        this.refs.rLifeCycle.forceItUpdate();
    }

    unmountLifeCycle() {
        // 這里卸載父組件也會導致卸載子組件
        React.unmountComponentAtNode(document.getElementById("container"));
    }

    parentForceUpdate() {
        this.forceUpdate();
    }

    render() {
        return (
            <div>
                <a href="javascript:;" className="weui_btn weui_btn_primary" onClick={this.propsChange.bind(this)}>propsChange</a>
                <a href="javascript:;" className="weui_btn weui_btn_primary" onClick={this.setLifeCycleState.bind(this)}>setState</a>
                <a href="javascript:;" className="weui_btn weui_btn_primary" onClick={this.forceLifeCycleUpdate.bind(this)}>forceUpdate</a>
                <a href="javascript:;" className="weui_btn weui_btn_primary" onClick={this.unmountLifeCycle.bind(this)}>unmount</a>
                <a href="javascript:;" className="weui_btn weui_btn_primary" onClick={this.parentForceUpdate.bind(this)}>parentForceUpdateWithoutChange</a>
                <LifeCycle ref="rLifeCycle" num={this.state.num}></LifeCycle>
            </div>
        );
    }
}

ReactDOM.render(
    <Container></Container>,
    document.getElementById('container')
);
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容