一起學React--元素渲染和生命週期

蘿蔔突擊發表於2019-03-10

1. JSX

JSX是Javascript的語法擴充,在React中通過JSX渲染元素

const name = 'Josh Perez';
const element = <h1>Hello, {name}</h1>;

ReactDOM.render(
  element,
  document.getElementById('root')
);
複製程式碼

類似模版渲染,jsx可以通過變數來定義,然後在React中渲染。

在jsx中定義一些屬性是使用的小駝峰的寫法,如className,tabIndex

Babel 會把 JSX 轉譯成一個名為 React.createElement() 函式呼叫。

const element = (
  <h1 className="greeting">
    Hello, world!
  </h1>
);

複製程式碼
const element = React.createElement(
  'h1',
  {className: 'greeting'},
  'Hello, world!'
);
複製程式碼

所以事實上jsx還是 React.createElement(component, props, ...children) 的語法糖。

2. React元素渲染

React中通過 ReactDOM.render 的方式渲染元素,配合上強大的jsx語法,一切皆為變數,一切在 {} 的變數都能被渲染。

function tick() {
  const element = (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {newDate().toLocaleTimeString()}.</h2>
    </div>
  );
  ReactDOM.render(element, document.getElementById('root'));
}

setInterval(tick, 1000);
複製程式碼

3. React生命週期

  • constructor()

執行建構函式

  • render()

渲染

  • componentDidMount()

在Dom樹渲染完成後立即呼叫componentDidMount()。需要DOM節點的初始化應該放在這裡。如果需要從遠端端點載入資料,這是例項化網路請求的好地方。

如果使用DidMount 記得要在元件使用之後取消訂閱,componentWillUnmount

  • shouldComponentUpdate() (比較少用)

當元件接收到新屬性,或者元件的狀態發生改變時觸發。元件首次渲染時並不會觸發

shouldComponentUpdate(newProps, newState) {
    if (newProps.number < 5) return true;
    return false
}
//該鉤子函式可以接收到兩個引數,新的屬性和狀態,返回true/false來控制元件是否需要更新。
複製程式碼

一般我們通過該函式來優化效能:一個React專案需要更新一個小元件時,很可能需要父元件更新自己的狀態。而一個父元件的重新更新會造成它旗下所有的子元件重新執行render()方法,形成新的虛擬DOM,再用diff演算法對新舊虛擬DOM進行結構和屬性的比較,決定元件是否需要重新渲染.無疑這樣的操作會造成很多的效能浪費,所以我們開發者可以根據專案的業務邏輯,在shouldComponentUpdate()中加入條件判斷,從而優化效能

  • componentDidUpdate()

元件更新

componentDidUpdate(prevProps, prevState, snapshot)

更新發生後立即呼叫componentDidUpdate()初始渲染不會呼叫此方法。

將此作為在更新元件時對DOM進行操作的機會。只要將當前props與之前的props進行比較(例如,如果props未更改,則可能不需要網路請求),這也是進行網路請求的好地方。

componentDidUpdate(prevProps) {
  // 不要忘了比較props的狀態
  if (this.props.userID !== prevProps.userID) {
    this.fetchData(this.props.userID);
  }
}
複製程式碼
  • componentWillUnmount()

元件解除安裝

在解除安裝和銷燬元件之前立即調componentWillUnmount()在此方法中執行任何必要的清理,例如使計時器無效,取消網路請求或清除在componentDidMount()中建立的任何訂閱。

  • componentDidCatch()

在渲染期間,生命週期方法或任何子元件的建構函式中發生錯誤時,將呼叫這些方法。

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

class SubCounter extends React.Component {
    // 在17版本將要廢棄,還是不用較好
    componentWillReceiveProps() {
        console.log('9、子元件將要接收到新屬性');
    }

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

    // 同17版本將要廢棄
    componentWillUpdate() {
        console.log('11、子元件將要更新');
    }

    componentDidUpdate() {
        console.log('13、子元件更新完成');
    }

    componentWillUnmount() {
        console.log('14、子元件將解除安裝');
    }

    render() {
        console.log('12、子元件掛載中');
        return (
                <p>{this.props.number}</p>
        )
    }
}


// 父元件
class Counter extends React.Component {
    static defaultProps = {
        //1、載入預設屬性
        name: 'sls',
        age:23
    };

    constructor() {
        super();
        //2、載入預設狀態
        this.state = {number: 0}
    }


    // 新版本已經廢棄
    componentWillMount() {
        console.log('3、父元件掛載之前');
    }

    componentDidMount() {
        console.log('5、父元件掛載完成');
    }

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


    // 新版本已經廢棄
    componentWillUpdate() {
        console.log('7、父元件將要更新');
    }

    componentDidUpdate() {
        console.log('8、父元件更新完成');
    }

    handleClick = () => {
        this.setState({
            number: this.state.number + 1
        })
    };

    render() {
        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('root'));

複製程式碼

最後附上生命週期圖示

一起學React--元素渲染和生命週期

一起學React--元素渲染和生命週期

參考連結 React生命週期

相關文章