React 中 render 函式的執行時機

奔跑吧_兄弟發表於2019-08-17

學習 React 已快有 3 個月了,在這裡通過分享學習心得,與大家一起交流,與大家一起每天進步。

在剛開始學習 React 的時候,我認為元件的 state 或者 props 改變時,就會觸發元件的 render 函式執行。後來我通過一系列的試驗發現,state 不改變也可以觸發 render 函式的執行,props 改變了也不一定觸發 render 函式的執行,下面通過一系列的 demo 說明這個觀點。

state不改變也可以觸發render函式的執行

直接上程式碼:

import React from 'react';
import ReactDOM from 'react-dom';

class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            message: 'click button',
        };
        this.handleClick = this.handleClick.bind(this);
    }

    handleClick() {
        console.log('Click happen');
        this.setState({});
    }

    render() {
        console.log('App render');
        const { message } = this.state;
        return (
            <button onClick={ this.handleClick }>{ message }</button>
        );
    }
}

ReactDOM.render(<App />, document.getElementById('root'));
複製程式碼

程式碼的思路很簡單,按鈕繫結一個點選事件,當點選按鈕時,執行 setState({}) 方法,由於 setState 方法的引數是一個空物件,state 並沒有改變,這時候觀察 render 函式是否執行,結果是執行了的,如下圖,所以,只要 setState 方法執行,render 函式就會執行。

setState({})執行結果

props改變了也不一定觸發render函式的執行

直接上程式碼:

import React, {Fragment} from 'react';
import ReactDOM from 'react-dom';

const obj = {
    message: 'hello world',
};

class App extends React.Component {
    handleClick() {
        console.log('click happen');
        obj.message = 'hello Beijing';
    }

    render() {
        return (
            <Fragment>
                <button onClick={ this.handleClick }>Click</button>
                <Component1 objMessage={ obj } />
            </Fragment>
        );
    }
}

class Component1 extends React.Component {
    render() {
        const { objMessage } = this.props;
        console.log('Component1 render');
        return (
            <div>{ objMessage.message }</div>
        );
    }
}

ReactDOM.render(<App />, document.getElementById('root'));
複製程式碼

程式碼思路很簡單,一個父元件 App,一個子元件 Component1,子元件的props來自於外部變數 obj,當我點選父元件的按鈕時,去改變外部變數 obj 物件的值,這時候去觀察子元件 Component1 的 render 函式是否執行,結果是沒有執行,如下圖,所以 props 改變了也不一定觸發 render 函式的執行。

props改變

總結

在 React 中,只要執行了 setState 方法,就一定會觸發 render 函式執行;元件的 props 改變了,不一定觸發 render 函式的執行,除非 props 的值來自於父元件或者祖先元件的 state,在這種情況下,元件的 props 改變,也就意味著父元件或者祖先元件的 state 發生了改變,也就是父元件或者祖先元件執行了 setState 方法;那麼可以總結出,render 函式的執行時機就是 setState 方法的執行。

另,render 函式執行並不一定意味著發生 DOM 操作,render 函式執行只是返回虛擬 DOM,需要通過比較新舊虛擬 DOM 來決定是否發生 DOM 操作,新舊虛擬 DOM 的比較,就涉及 diff 演算法了,這又是另一個話題了。

相關文章