儘可能全面詳細的整理一下React的生命週期中的知識點。javascript
組件是獨立的封裝的能夠複用的一個小部件,它是React的核心思想之一。經過劃分組件,能夠將一個頁面劃分紅獨立的多個可複用的組件,各個組件經過嵌套、組合造成一個完整的頁面。java
在React中,組件基本由三個部分組成:屬性(props)、狀態(state)以及生命週期方法。能夠將組件簡單地看做一個「狀態機」,根據不一樣的state
和props
呈現不一樣的UI,經過與用戶的交互實現不一樣的狀態,而後從新渲染組件,UI能夠跟隨數據變化而變化。react
組件常分爲兩種:Class Component
和Functional Component
。設計模式
Functional Component
也稱爲無狀態組件,它多用於純展現組件,這種組件只負責根據傳入的props
來渲染組件,而不涉及state
狀態管理。數組
在大部分React代碼中,大多數組件被寫成無狀態的組件,經過簡單組合能夠構建成其餘的組件等;這種經過多個簡單而後合併成一個大應用的設計模式被提倡。網絡
無狀態組件能夠經過函數形式或者ES6的箭頭函數來建立:異步
// 函數 function HelloFunctional(props){ return <div>hello {props.name}</div>; } // ES6箭頭函數 const HelloFunctional = (props) => (<div>hello {props.name}</div>);
無狀態組件有如下幾個特色:函數
props
,一樣的輸入必定會有一樣的輸出因此,在項目中若是不須要進行狀態管理,應該儘可能寫成無狀態組件的形式。性能
如今主流的建立有狀態組件的形式是經過ES6的Class來建立,取代React.createClass
:this
Class HelloClass extends React.Component{ constructor(){ this.state = { name:'axuebin' } } render(){ return (<div>hello {this.state.name}</div>); } }
這是最簡潔的一個組件,它須要使用到內部狀態state
。
當組件須要使用內部狀態時或者須要使用生命週期方法時就須要使用有狀態組件。
React組件的生命週期能夠分爲掛載、渲染和卸載這幾個階段,當渲染後的組件更新後,會從新渲染組件,直到卸載。先分階段來看看每一個階段有哪些生命週期函數。
屬於這個階段的生命週期函數有:
constructor() { super(); this.state = {name: 'axuebin'}; this.handleClick = this.handleClick.bind(this); }
這個階段就是組件的初始化,constructor()
能夠理解爲組件的構造函數,從組件的類class
實例化一個組件實例。這個函數是組件造成時就被調用的,是生命週期中最早執行的。
在constructor()
函數內,首先必須執行super()
,不然this.props
將是未定義,會引起異常。
而後,若是有必要,能夠進行:
state
的初始化若是不須要這兩步,能夠直接省略constructor
函數。
這個函數按照駝峯法的命名規則能夠理解爲「組件即將被掛載」,因此這個函數是組件首次渲染(render)前調用的。
在每次頁面加載、刷新時,或者某個組件第一次展示時都會調用這個函數。一般地,咱們推薦使用constructor()
來替代。
注意:在這個函數中,不能夠調用setState
來修改狀態。
render() { return( <div>hello {this.state.name} {this.props.age}</div> ) }
render()
在生命週期中是必須的,是渲染組件用的。
當這個函數被調用時,須要檢查this.props
和this.state
而且返回一個元素(有且只有一個元素),這個元素多是一個原生DOM元素,也有多是另外一個React組件。
能夠在state
或props
狀態爲空時試着返回一個null
或者false
來聲明不想渲染任何東西。
在這個函數中,不該該改變組件的狀態,也就是不執行this.setState
,須要保持render()
函數的純淨。
在這個函數中,能夠對props
進行調用並組合,但不可修改。
componentDidMount() { this.setState({name:'xb'}); }
這個函數在組件加載渲染完成後當即調用,此時頁面上已經渲染出真實的DOM了,能夠在這個函數中訪問到真實的DOM(能夠經過this.refs
來訪問真實DOM)。
在這個階段,還能夠作一件事,能夠修改state
了!!!
並且,異步獲取數據在這個階段執行也是比較合理的,獲取數據以後setState
,而後從新渲染組件。
屬性或狀態的改變會觸發一次更新。當一個組件在被從新渲染時,這些方法將會被調用:
已加載的組件在props
發生變化時調用,若須要更新狀態,可能須要對比this.props
和nextProps
而後在該方法中使用this.setState
來處理狀態的改變。
須要注意的是,有些狀況下,即便props
未改變也會觸發該函數,因此必定要先比較this.props
和nextProps
再作操做。
該函數只監聽props
的改變,this.setState
不會觸發這個函數。
componentWillReceiveProps(nextProps){ if (this.props.color !== nextProps.color){ this.setState({}); } }
這個函數只返回true
或false
,表示組件是否須要更新(從新渲染)。
true
就是緊接着如下的生命週期函數;false
表示組件不須要從新渲染,再也不執行任何生命週期函數(包括render)。這個函數使用需謹慎,react官方文檔中說道,在將來這個函數返回false
可能仍然使得組件從新渲染。
這個函數看名字就和componentWillMount
很像,它執行的階段也很像。在接收到新的props
或者state
以後,這個函數就會在render
前被調用。
一樣的,在這個函數中不能使用this.setState()
。若是須要更新狀態,請在componentWillReceiveProps
中調用this.setState()
。
又是一次的render
。這和掛載階段的render
有什麼區別呢?
在函數的性質上來講,二者毫無區別,只不過是在生命週期的不一樣階段的調用。
render
是在組件第一次加載時調用的,也就是初次渲染,能夠理解爲mount
;render
是除去第一次以後調用的,也就是再渲染,re-render
;一樣地,這個方法是在組件re-render
以後調用的,該方法不會在初始化的時候調用。和componentDidMount
同樣,在這個函數中可使用this.refs
獲取真實DOM。
還能夠修改state
哦,不過會致使組件再次re-render
。
該方法將會在 component 從DOM中移除時調用
卸載階段就很簡單了,就這一個生命週期函數,在組件被卸載和銷燬以前馬上調用。
在這個函數中,應該處理任何須要的清理工做,好比銷燬定時器、取消網絡請求、清除以前建立的相關DOM節點等。