React 生命週期鉤子

概念---什麼是生命週期鉤子

React官方文檔中說到:在組件類上聲明特殊的方法,當組件掛載或卸載時,來運行一些代碼,這些方法被稱做生命週期鉤子。html

生命週期圖解

clipboard.png

在官方文檔給出的組件生命週期的圖中,咱們能夠很清楚的認識到,一個React組件的生命週期主要分爲3個階段:建立時、更新時、卸載時。node

建立時階段

當組件處於初始化階段時,依次調用:react

  1. defaultProps(默認狀態,通常用於若是父組件調用子組件的時候不給子組件傳值,能夠在子組件中使用defaultProps定義的默認值)
// defaultProps初始化props,只會調用一次
class Hello extends React.Component {
    static defaultProps = {
      name: 'Lily',
      age: 13
    }
    render: function(){
            return (
                <div>Hello,{this.props.name}</div>
            )
        }
}

注意: React.PropTypes 自 React v15.5 起已棄用,官方推薦使用使用prop-types代替npm

// 類型檢測
import PropTypes from 'prop-types';

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

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

  1. constructor
If you don’t initialize state and you don’t bind methods, you don’t need to implement a constructor for your React component.

The constructor for a React component is called before it is mounted. When implementing the constructor for a React.Component subclass, you should call super(props) before any other statement. Otherwise, this.props will be undefined in the constructor, which can lead to bugs.segmentfault


官方文檔中描述到constructor只是是用來初始化狀態和爲實例綁定函數的,而且在組件掛載以前被調用。瀏覽器

class Hello extends React.Component {
  constructor(props) {
    // 
    super(props);
    // 此處不能夠調用this.setState();
    this.state = {data: 'Hello world'};
  }

  render() {
    return (
      <div>
        <h1>{this.state.data}</h1>
      </div>
    );
  }
}

同時也要注意,this.state = { color: props.color };這種寫法是不正確的。而且避免在constructor中聲明介紹 side-effects(反作用) 或者 subscriptions(訂閱)性能優化


3. componentWillMount(UNSAFE_componentWillMount())
componentWillMount發生在組件掛載以前 ,在render以前調用,所以在此方法中同步調用setState()不會觸發額外的渲染。
componentWillMount也不能聲明介紹 side-effects(反作用) 或者 subscriptions(訂閱)網絡


4. render
render()方法是惟一一個類組件必需的方法。當調用時會檢查this.props 和 this.state,而後返回如下類型:less

  • React elements,相似於: <div /> ,<MyComponent />。
  • Arrays and fragments。Fragments可讓你在不新增DOM節點的同時返回一個組件列表。
render() {
  return (
    <React.Fragment>
      <ChildA />
      <ChildB />
      <ChildC />
    </React.Fragment>
  );
}
  • Portals。正常狀況下,子組件掛載在最接近的父節點下,可是Portals能夠將子級呈現到父組件的DOM層次結構以外的DOM節點中,ReactDOM.createPortal(child, container)包含兩個參數:child---任意可渲染的 React 組件, container--- DOM節點。
render() {
  // React does *not* create a new div. It renders the children into `domNode`.
  // `domNode` is any valid DOM node, regardless of its location in the DOM.
  return ReactDOM.createPortal(
    this.props.children,
    domNode
  );
}
  • String 和 numbers。
  • Booleans 和 null。

render 是純粹的, 不能在 render 方法中修改組件狀態,同時 render 也不直接和瀏覽器交互。dom


5. componentDidMount
componentDidMount() 在組件掛載以後當即調用,能夠在此處初始化須要的節點,也能夠在此處調用服務和事件訂閱。由於該方法被調用時,真實DOM已經被渲染,因此能夠用來訪問DOM節點,相似於Modal、tooltips等組件。官方文檔建議儘可能不要在此方法內使用setState(),由於儘管用戶不會看見中間狀態,可是也可能引起性能問題。

更新時階段

在更新時階段,也能夠說是運行時階段,組件已經渲染完成,用戶能夠和組件進行交互,並觸發狀態改變,進入新的生命週期。
1. componentWillReceiveProps
在一個已經掛載完成的組件的收到一個新的props,將會調用componentWillReceiveProps方法去比較 this.propsnextProps 是否不同,而後this.setState()更新state。

componentWillReceiveProps(nextProps){
    if(nextProps.value === this.props.value){
        this.setState({...});
    }
}

2. shouldComponentUpdate
shouldComponentUpdate(),是生命週期的一個性能優化點,可以知道組件的輸出是否不受當前狀態或屬性更改的影響。咱們能夠在這個方法裏經過返回 false 來阻止組件的從新渲染,返回 false 則不會執行 render ,componentWillUpdate,componentDidUpdate 方法。可是返回 false 不會阻止子組件在狀態改變後從新渲染。

shouldComponentUpdate(nextProps, nextState){
    return true;
}

3. componentWillUpdate
componentWillUpdate 方法在組件接收到了新的props或者state即將從新渲染以前被調用。可是注意不能在此方法使用this.setState(),也不能在componentWillUpdate()方法返回以前進行其餘可以更新React 組件的操做。

UNSAFE_componentWillUpdate(nextProps, nextState)


4. componentDidUpdate
componentDidUpdate(object prevProps, object prevState) 方法在組件從新被渲染以後會被調用,能夠在這裏操做 DOM和狀態修改。在修改狀態時,要注意setState() 方法要在條件嵌套中調用,不然會引發死循環。

componentDidUpdate(prevProps) {
  if (this.props.value !== prevProps.value) {
    this.fetchData(this.props.value);
  }
}

卸載時階段

componentWillUnmount 方法在組件卸載和銷燬以前被調用,能夠在這個方法裏執行清除。好比,定時器和事件訂閱,以及撤銷網絡請求。

總結

組件生命週期

關於內容

React官方文檔特別詳述了生命週期鉤子函數以及各個鉤子函數的關係,我的建議從官方文檔閱讀總結。

關於文章

第一次寫技術文章,可能不少地方寫的不是很好,但願你們多多指正,爭取在下一篇,寫的更好(這多是個flag)。

疑問

一、在官方文檔中componentWillMount有一句描述,我的不是很理解:This is the only lifecycle method called on server rendering. 但願有大佬能夠爲我答疑。

參考文章

React組件
React: 組件的生命週期

相關文章
相關標籤/搜索