React組件生命周期

生命周期流程圖簡單如下:

組件讓你把用戶界面分成獨立的,可重復使用的部分,并且將每個部分分開考慮。React.Component由...提供React


React.Component是一個抽象的基類,所以React.Component直接引用很少有意義。相反,您通常會將其子類化,并定義至少一個render()方法。

通常情況下,您可以將一個React組件定義為一個普通的JavaScript類

class Greeting extends React.Component{

render(){

return Hello,{this.props.name};

}

}

如果您還沒有使用ES6,則可以使用該create-react-class模塊??纯?a target="_blank" rel="nofollow">使用沒有ES6的React來了解更多。

組件生命周期

每個組件都有幾個“生命周期方法”,您可以在進程中的某些特定時間重寫以運行代碼。will在事件發生之前調用帶有前綴的方法,并且did在事件發生之后調用帶有前綴的方法。

安裝

當創建一個組件的實例并將其插入到DOM中時,將調用這些方法:

constructor()

componentWillMount()

render()

componentDidMount()

更新

更新可以由道具或狀態的更改引起。當一個組件被重新渲染時,這些方法被調用:

componentWillReceiveProps()

shouldComponentUpdate()

componentWillUpdate()

render()

componentDidUpdate()

卸載

從DOM中刪除組件時調用此方法:

componentWillUnmount()

錯誤處理

在渲染期間,生命周期方法或任何子組件的構造函數中發生錯誤時調用此方法。

componentDidCatch()

其他API

每個組件還提供一些其他API:

setState()

forceUpdate()

類屬性

defaultProps

displayName

實例屬性

props

state

參考

render()

render()

該render()方法是必需的。

被調用時,應該檢查this.props并this.state返回以下類型之一:

React元素。通常通過JSX創建。元素可以是本地DOM組件()的表示,也可以是用戶定義的組合組件()。

字符串和數字。這些在DOM中呈現為文本節點。

門戶網站。創建于ReactDOM.createPortal

null。不渲染任何東西。

布爾人。什么都不渲染。(主要存在支持return test && 模式,其中test是布爾值。)

當返回null或false,ReactDOM.findDOMNode(this)將返回null。

該render()函數應該是純粹的,意味著它不會修改組件狀態,每次調用時都會返回相同的結果,并且不會直接與瀏覽器交互。如果您需要與瀏覽器進行交互,請componentDidMount()改為使用其他生命周期方法。保持render()純粹使組件更容易思考。

注意

render()如果shouldComponentUpdate()返回false,則不會被調用。

片段

您也可以render()使用數組返回多個項目:

render(){return[First item,Second item,Third item,];}

注意:

不要忘記添加鍵到片段中的元素,以避免重要的警告。

constructor()

constructor(props)

React組件的構造函數在掛載之前被調用。在實現React.Component子類的構造函數時,應該super(props)在任何其他語句之前調用。否則,this.props會在構造函數中定義,這可能會導致錯誤。

避免在構造函數中引入任何副作用或訂閱。對于這些用例,請componentDidMount()改為使用。

構造函數是初始化狀態的正確位置。要做到這一點,只需分配一個對象this.state;?不要嘗試setState()從構造函數調用。構造函數也經常用于將事件處理程序綁定到類實例。

如果您不初始化狀態,并且不綁定方法,則不需要為React組件實現構造函數。

在極少數情況下,可以根據道具初始化狀??態。這有效地“叉”的道具,并設置與初始道具的狀態。下面是一個有效的React.Component子類構造函數的例子:

constructor(props){super(props);this.state={color:props.initialColor};}

小心這種模式,因為國家將不會更新任何道具。而不是將道具同步到狀態,而是經常想要提升狀態

如果你使用他們的狀態“叉”道具,你也可能想要執行,componentWillReceiveProps(nextProps)以保持狀態與他們最新。但是提升狀態通常更容易,并且更少出現錯誤。

componentWillMount()

componentWillMount()

componentWillMount()在安裝發生之前立即被調用。它之前被調用render(),因此setState()在這個方法中同步調用不會觸發額外的渲染。一般來說,我們推薦使用constructor()。

避免在此方法中引入任何副作用或訂閱。對于這些用例,請componentDidMount()改為使用。

這是在服務器渲染上調用的唯一的生命周期鉤子。

componentDidMount()

componentDidMount()

componentDidMount()在組件被裝載后立即被調用。需要DOM節點的初始化應該在這里。如果您需要從遠程端點加載數據,這是一個實例化網絡請求的好地方。

這種方法是設置任何訂閱的好地方。如果你這樣做,不要忘記退訂componentWillUnmount()。

調用setState()這個方法會觸發一個額外的渲染,但在瀏覽器更新屏幕之前會發生。這保證即使render()在這種情況下將被調用兩次,用戶也不會看到中間狀態。請謹慎使用此模式,因為這通常會導致性能問題。但是,當需要在渲染依賴于其大小或位置的東西之前測量DOM節點時,可能需要類似于模態和工具提示的情況。

componentWillReceiveProps()

componentWillReceiveProps(nextProps)

componentWillReceiveProps()在安裝的組件接收新的道具之前被調用。如果您需要在響應更新狀態托變化(例如,復位),你可以比較this.props和nextProps和執行使用狀態轉換this.setState()在此方法。

請注意,即使道具尚未更改,React也可能會調用此方法,因此如果您只想處理更改,請務必比較當前值和下一個值。父組件導致組件重新呈現時,可能會發生這種情況。

componentWillReceiveProps()在安裝過程中,反應不會與初始道具呼叫。只有在組件的某些道具可能更新時才會調用這個方法。調用this.setState()通常不會觸發componentWillReceiveProps()。

shouldComponentUpdate()

shouldComponentUpdate(nextProps,nextState)

使用shouldComponentUpdate()讓陣營知道,如果一個組件的輸出不會受到州或道具的電流變化。默認行為是在每次狀態更改時重新呈現,在絕大多數情況下,您應該依靠默認行為。

shouldComponentUpdate()在渲染新的道具或狀態時被調用。默認為true。此方法不用于初始渲染或何時forceUpdate()使用。

返回false不會阻止子組件在狀態更改時重新呈現。

目前,如果shouldComponentUpdate()回報false,然后componentWillUpdate(),render()componentDidUpdate()將不會被調用。請注意,將來React可能會被shouldComponentUpdate()視為提示而不是嚴格的指令,并且返回false可能仍會導致組件的重新呈現。

如果確定特定組件在分析后緩慢,則可以將其更改為從具有較淺支撐和狀態比較的React.PureComponent哪些實現中繼承shouldComponentUpdate()。如果你確信你想用手寫,你可以比較this.props,nextProps并this.state與nextState返回false告訴React更新可以跳過。

我們不建議這樣做深平等檢查或使用JSON.stringify()在shouldComponentUpdate()。這是非常低效的,會損害性能。

componentWillUpdate()

componentWillUpdate(nextProps,nextState)

componentWillUpdate()在渲染新的道具或狀態時立即被調用。使用這個機會在更新發生之前執行準備工作。這個方法不是為初始渲染調用的。

請注意,你不能this.setState()在這里打電話;?你也不應該做任何其他的事情(比如派遣一個Redux動作),在componentWillUpdate()返回之前觸發一個React組件的更新。

如果您需要更新state以響應props更改,請componentWillReceiveProps()改為使用。

注意

componentWillUpdate()如果shouldComponentUpdate()返回false,則不會被調用。

componentDidUpdate()

componentDidUpdate(prevProps,prevState)

componentDidUpdate()在更新發生后立即被調用。這個方法不是為初始渲染調用的。

當組件更新時,可以使用這個機會來操作DOM。只要你將目前的道具與以前的道具進行比較,這也是一個很好的做網絡請求的地方(例如,如果道具沒有改變,可能不需要網絡請求)。

注意

componentDidUpdate()如果shouldComponentUpdate()返回false,則不會被調用。

componentWillUnmount()

componentWillUnmount()

componentWillUnmount()在組件被卸載并銷毀之前立即被調用。在這個方法中執行任何必要的清理,例如使定時器無效,取消網絡請求,或者清理在其中創建的任何訂閱componentDidMount()。

componentDidCatch()

componentDidCatch(error,info)

錯誤邊界是React組件,可以在其子組件樹中的任何位置捕獲JavaScript錯誤,記錄這些錯誤,并顯示備用UI而不是崩潰的組件樹。錯誤邊界在渲染,生命周期方法以及整個樹下的構造函數中捕獲錯誤。

如果一個類組件定義了這個生命周期方法,它將成為一個錯誤邊界。調用setState()它可以在下面的樹中捕獲未處理的JavaScript錯誤,并顯示一個后備UI。只能使用錯誤邊界從意外的異常中恢復;?不要試圖將它們用于控制流程。

有關更多詳細信息,請參閱React 16中的錯誤處理。

注意

錯誤邊界只會捕獲樹中下面的組件中的錯誤。錯誤邊界本身不能捕獲錯誤。

setState()

setState(updater[,callback])

setState()將更改排入組件狀態,并告訴React該組件及其子組件需要使用更新的狀態重新呈現。這是用來更新用戶界面以響應事件處理程序和服務器響應的主要方法。

將其setState()看作是一個請求,而不是一個立即的命令來更新組件。為了獲得更好的感知性能,React可能會延遲它,然后一次更新幾個組件。React不保證立即應用狀態更改。

setState()并不總是立即更新組件。它可能會批處理或推遲更新,直到更晚。這使得閱讀this.state正確后,setState()可能會陷入困境。相反,使用componentDidUpdate或setState回調(setState(updater, callback)),其中任何一個保證在應用更新后觸發。如果您需要根據以前的狀態設置狀態,請閱讀updater下面的參數。

setState()總是會導致重新呈現,除非shouldComponentUpdate()得到回報false。如果正在使用可變對象并且無法實現條件呈現邏輯shouldComponentUpdate(),則setState()僅在新狀態與先前狀態不同時調用將避免不必要的重新呈現。

第一個參數是updater帶簽名的函數:

(prevState,props)=>stateChange

prevState是對以前的狀態的參考。它不應該直接變異。相反,應根據來自prevState和的輸入構建新對象來表示更改props。例如,假設我們想通過以下方式增加一個狀態值props.step:

this.setState((prevState,props)=>{return{counter:prevState.counter+props.step};});

二者prevState并props通過更新功能接收保證是向上的更新。更新程序的輸出與淺層合并prevState。

第二個參數setState()是一個可執行的回調函數,將被執行一次setState完成,并重新渲染組件。通常我們推薦使用componentDidUpdate()這樣的邏輯來代替。

你可以選擇傳遞一個對象作為第一個參數來setState()代替函數:

setState(stateChange[,callback])

這會執行stateChange到新狀態的淺層合并,例如調整購物車項目數量:

this.setState({quantity:2})

這種形式setState()也是異步的,并且在同一個周期內的多個調用可以一起進行批處理。例如,如果您嘗試在同一個周期內多次增加一個項目數量,那么將導致等同于:

Object.assign(previousState,{quantity:state.quantity+1},{quantity:state.quantity+1},...)

隨后的調用將覆蓋同一周期中先前調用的值,因此數量只會增加一次。如果下一個狀態取決于之前的狀態,我們建議使用更新函數形式,而不是:

this.setState((prevState)=>{return{quantity:prevState.quantity+1};});

有關更多詳細信息,請參閱州和生命周期指南

forceUpdate()

component.forceUpdate(callback)

默認情況下,當組件的狀態或者道具改變時,你的組件將重新渲染。如果你的render()方法依賴于其他數據,你可以通過調用告訴React組件需要重新渲染forceUpdate()。

調用forceUpdate()將導致render()在組件上調用,跳過shouldComponentUpdate()。這將觸發子組件的正常生命周期方法,包括shouldComponentUpdate()每個子組件的方法。如果標記更改,React將只會更新DOM。

通常情況下,你應該盡量避免所有的使用forceUpdate()和只讀this.props和this.state中render()。

類屬性

defaultProps

defaultProps可以被定義為組件類本身的一個屬性,來設置該類的默認道具。這用于未定義的道具,但不適用于null道具。例如:

classCustomButtonextendsReact.Component{// ...}CustomButton.defaultProps={color:'blue'};

如果props.color沒有提供,它將被默認設置為'blue':

render(){return;// props.color will be set to blue}

如果props.color設置為空,它將保持為空:

render(){return;// props.color will remain null}

displayName

該displayName字符串用于調試消息。通常,您不需要明確設置它,因為它是從定義組件的函數或類的名稱推斷出來的。如果要為調試目的顯示不同的名稱,或者要創建高階組件,則可能需要顯式設置它,有關詳細信息,請參閱包裝顯示名稱以進行簡單調試。

實例屬性

props

this.props包含由該組件的調用者定義的道具。請參閱組件和道具以了解道具的介紹。

特別是,它this.props.children是一個特殊的道具,通常由JSX表達式中的子標簽定義,而不是標簽本身。

state

狀態包含特定于此組件的數據,可能隨時間而改變。狀態是用戶定義的,它應該是一個普通的JavaScript對象。

如果你不使用它render(),它不應該在這個狀態。例如,您可以將計時器ID直接放在實例上。

有關狀態的更多信息,請參閱狀態和生命周期

不要this.state直接變異,因為setState()之后的調用可能會取代你所做的變異。把this.state它看作是不可改變的。



visio下載地址:react組件生命周期


?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 下面所寫的,只適合前端的React。(React也支持后端渲染,而且和前端有點小區別,不過我沒用過。) 相關函數 ...
    linjinhe閱讀 177,111評論 28 208
  • 相關函數 簡單地說,React Component通過其定義的幾個函數來控制組件在生命周期的各個階段的動作。在ES...
    Allan要做活神仙閱讀 296評論 0 0
  • 組件生命周期 參考閱讀: component-lifecycle react組件生命周期過程說明 react 組件...
    lyzaijs閱讀 2,530評論 0 3
  • component是通過自定義的幾個函數來控制組件在生命周期中的各個階段動作(本處所寫的state同意指當前組件內...
    冰Q閱讀 447評論 0 0
  • 南風催柳綠,晨鳥喚春回。 花間蜂蝶已雙對,旅雁歸不歸。 猶喜艷陽照,幽芳入心扉。 客居江南惹風雨,不忍與相違。
    孤祭閱讀 291評論 0 1