標籤:

圖解ES6中的React生命周期

  • 子組件和父組件componentDidMount哪一個先執行

import React, { Component } from react;nclass Test extends Component{n componentWillMount(){n console.log(子組件將要掛載)n }n render(){n return(<p>{this.props.index}</p>)n }n}nnexport default class TestPanel extends Component{n componentDidMount(){n console.log(父組件掛載完畢);n }n render(){n return(n <div>n <Test index={1}/>n <Test index={2}/>n <Test index={3}/>n </div>n )n }n}n

前言

如果將React的生命周期比喻成一隻螞蟻爬過一根吊繩,那麼這隻螞蟻從繩頭爬到繩尾,就會依次觸動不同的卡片掛鉤。在React每一個生命周期中,也有類似卡片掛鉤的存在,我們把它稱之為『鉤子函數』。那麼在React的生命周期中,到底有哪些鉤子函數?React的生命周期又是怎樣的流程?今天我給大家來總結總結

React 生命周期

如圖,React生命周期主要包括三個階段:初始化階段、運行中階段和銷毀階段,在React不同的生命周期里,會依次觸發不同的鉤子函數,下面我們就來詳細介紹一下React的生命周期函數

一、初始化階段

1、設置組件的默認屬性

static defaultProps = {n name: sls,n age:23n};n//ornCounter.defaltProps={name:sls}n

2、設置組件的初始化狀態

constructor() {n super();n this.state = {number: 0}n}n

3、componentWillMount()

組件即將被渲染到頁面之前觸發,此時可以進行開啟定時器、向伺服器發送請求等操作

4、render()

組件渲染

5、componentDidMount()

組件已經被渲染到頁面中後觸發:此時頁面中有了真正的DOM的元素,可以進行DOM相關的操作

二、運行中階段

1、componentWillReceiveProps()

組件接收到屬性時觸發

2、shouldComponentUpdate()

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

shouldComponentUpdate(newProps, newState) {n if (newProps.number < 5) return true;n return falsen}n

//該鉤子函數可以接收到兩個參數,新的屬性和狀態,返回true/false來控制組件是否需要更新。

一般我們通過該函數來優化性能:

一個React項目需要更新一個小組件時,很可能需要父組件更新自己的狀態。而一個父組件的重新更新會造成它旗下所有的子組件重新執行render()方法,形成新的虛擬DOM,再用diff演算法對新舊虛擬DOM進行結構和屬性的比較,決定組件是否需要重新渲染

無疑這樣的操作會造成很多的性能浪費,所以我們開發者可以根據項目的業務邏輯,在shouldComponentUpdate()中加入條件判斷,從而優化性能

例如React中的就提供了一個PureComponent的類,當我們的組件繼承於它時,組件更新時就會默認先比較新舊屬性和狀態,從而決定組件是否更新。值得注意的是,PureComponent進行的是淺比較,所以組件狀態或屬性改變時,都需要返回一個新的對象或數組

3、componentWillUpdate()

組件即將被更新時觸發

4、componentDidUpdate()

組件被更新完成後觸發。頁面中產生了新的DOM的元素,可以進行DOM操作

三、銷毀階段

1、componentWillUnmount()

組件被銷毀時觸發。這裡我們可以進行一些清理操作,例如清理定時器,取消Redux的訂閱事件等等。

有興趣的同學也可以用下面的代碼進行測試

廢話少說,放碼過來!

import React from reactnimport ReactDOM from react-dom;nnclass SubCounter extends React.Component {n componentWillReceiveProps() {n console.log(9、子組件將要接收到新屬性);n }nn shouldComponentUpdate(newProps, newState) {n console.log(10、子組件是否需要更新);n if (newProps.number < 5) return true;n return falsen }nn componentWillUpdate() {n console.log(11、子組件將要更新);n }nn componentDidUpdate() {n console.log(13、子組件更新完成);n }nn componentWillUnmount() {n console.log(14、子組件將卸載);n }nn render() {n console.log(12、子組件掛載中);n return (n <p>{this.props.number}</p>n )n }n}nnclass Counter extends React.Component {n static defaultProps = {n //1、載入默認屬性n name: sls,n age:23n };nn constructor() {n super();n //2、載入默認狀態n this.state = {number: 0}n }nn componentWillMount() {n console.log(3、父組件掛載之前);n }nn componentDidMount() {n console.log(5、父組件掛載完成);n }nn shouldComponentUpdate(newProps, newState) {n console.log(6、父組件是否需要更新);n if (newState.number<15) return true;n return falsen }nn componentWillUpdate() {n console.log(7、父組件將要更新);n }nn componentDidUpdate() {n console.log(8、父組件更新完成);n }nn handleClick = () => {n this.setState({n number: this.state.number + 1n })n };nn render() {n console.log(4、render(父組件掛載));n return (n <div>n <p>{this.state.number}</p>n <button onClick={this.handleClick}>+</button>n {this.state.number<10?<SubCounter number={this.state.number}/>:null}n </div>n )n }n}nReactDOM.render(<Counter/>, document.getElementById(root));n

ps:我是一個正在找工作的前端小白,前端前輩們公司有需要的話,給個機會吧


推薦閱讀:

Build Your Own React:第一次渲染
如何做一個支持轉場動畫的路由?
WordPress 決定停止使用 React
Weex 和 React Native 的根本區別在哪裡?
React.js: web開發者的14個工具和資源

TAG:React |