組件讓你把用戶(hù)界面分成獨(dú)立的,可重復(fù)使用的部分,并且將每個(gè)部分分開(kāi)考慮。React.Component由...提供React。
React.Component是一個(gè)抽象的基類(lèi),所以React.Component直接引用很少有意義。相反,您通常會(huì)將其子類(lèi)化,并定義至少一個(gè)render()方法。
通常情況下,您可以將一個(gè)React組件定義為一個(gè)普通的JavaScript類(lèi):
class Greeting extends React.Component{
render(){
return Hello,{this.props.name};
}
}
如果您還沒(méi)有使用ES6,則可以使用該create-react-class模塊。看看使用沒(méi)有ES6的React來(lái)了解更多。
每個(gè)組件都有幾個(gè)“生命周期方法”,您可以在進(jìn)程中的某些特定時(shí)間重寫(xiě)以運(yùn)行代碼。will在事件發(fā)生之前調(diào)用帶有前綴的方法,并且did在事件發(fā)生之后調(diào)用帶有前綴的方法。
當(dāng)創(chuàng)建一個(gè)組件的實(shí)例并將其插入到DOM中時(shí),將調(diào)用這些方法:
更新可以由道具或狀態(tài)的更改引起。當(dāng)一個(gè)組件被重新渲染時(shí),這些方法被調(diào)用:
從DOM中刪除組件時(shí)調(diào)用此方法:
在渲染期間,生命周期方法或任何子組件的構(gòu)造函數(shù)中發(fā)生錯(cuò)誤時(shí)調(diào)用此方法。
每個(gè)組件還提供一些其他API:
render()
該render()方法是必需的。
被調(diào)用時(shí),應(yīng)該檢查this.props并this.state返回以下類(lèi)型之一:
React元素。通常通過(guò)JSX創(chuàng)建。元素可以是本地DOM組件()的表示,也可以是用戶(hù)定義的組合組件()。
字符串和數(shù)字。這些在DOM中呈現(xiàn)為文本節(jié)點(diǎn)。
門(mén)戶(hù)網(wǎng)站。創(chuàng)建于ReactDOM.createPortal。
null。不渲染任何東西。
布爾人。什么都不渲染。(主要存在支持return test && 模式,其中test是布爾值。)
當(dāng)返回null或false,ReactDOM.findDOMNode(this)將返回null。
該render()函數(shù)應(yīng)該是純粹的,意味著它不會(huì)修改組件狀態(tài),每次調(diào)用時(shí)都會(huì)返回相同的結(jié)果,并且不會(huì)直接與瀏覽器交互。如果您需要與瀏覽器進(jìn)行交互,請(qǐng)componentDidMount()改為使用其他生命周期方法。保持render()純粹使組件更容易思考。
注意
render()如果shouldComponentUpdate()返回false,則不會(huì)被調(diào)用。
您也可以render()使用數(shù)組返回多個(gè)項(xiàng)目:
render(){return[First item,Second item,Third item,];}
注意:
不要忘記添加鍵到片段中的元素,以避免重要的警告。
constructor(props)
React組件的構(gòu)造函數(shù)在掛載之前被調(diào)用。在實(shí)現(xiàn)React.Component子類(lèi)的構(gòu)造函數(shù)時(shí),應(yīng)該super(props)在任何其他語(yǔ)句之前調(diào)用。否則,this.props會(huì)在構(gòu)造函數(shù)中定義,這可能會(huì)導(dǎo)致錯(cuò)誤。
避免在構(gòu)造函數(shù)中引入任何副作用或訂閱。對(duì)于這些用例,請(qǐng)componentDidMount()改為使用。
構(gòu)造函數(shù)是初始化狀態(tài)的正確位置。要做到這一點(diǎn),只需分配一個(gè)對(duì)象this.state;?不要嘗試setState()從構(gòu)造函數(shù)調(diào)用。構(gòu)造函數(shù)也經(jīng)常用于將事件處理程序綁定到類(lèi)實(shí)例。
如果您不初始化狀態(tài),并且不綁定方法,則不需要為React組件實(shí)現(xiàn)構(gòu)造函數(shù)。
在極少數(shù)情況下,可以根據(jù)道具初始化狀??態(tài)。這有效地“叉”的道具,并設(shè)置與初始道具的狀態(tài)。下面是一個(gè)有效的React.Component子類(lèi)構(gòu)造函數(shù)的例子:
constructor(props){super(props);this.state={color:props.initialColor};}
小心這種模式,因?yàn)閲?guó)家將不會(huì)更新任何道具。而不是將道具同步到狀態(tài),而是經(jīng)常想要提升狀態(tài)。
如果你使用他們的狀態(tài)“叉”道具,你也可能想要執(zhí)行,componentWillReceiveProps(nextProps)以保持狀態(tài)與他們最新。但是提升狀態(tài)通常更容易,并且更少出現(xiàn)錯(cuò)誤。
componentWillMount()
componentWillMount()在安裝發(fā)生之前立即被調(diào)用。它之前被調(diào)用render(),因此setState()在這個(gè)方法中同步調(diào)用不會(huì)觸發(fā)額外的渲染。一般來(lái)說(shuō),我們推薦使用constructor()。
避免在此方法中引入任何副作用或訂閱。對(duì)于這些用例,請(qǐng)componentDidMount()改為使用。
這是在服務(wù)器渲染上調(diào)用的唯一的生命周期鉤子。
componentDidMount()
componentDidMount()在組件被裝載后立即被調(diào)用。需要DOM節(jié)點(diǎn)的初始化應(yīng)該在這里。如果您需要從遠(yuǎn)程端點(diǎn)加載數(shù)據(jù),這是一個(gè)實(shí)例化網(wǎng)絡(luò)請(qǐng)求的好地方。
這種方法是設(shè)置任何訂閱的好地方。如果你這樣做,不要忘記退訂componentWillUnmount()。
調(diào)用setState()這個(gè)方法會(huì)觸發(fā)一個(gè)額外的渲染,但在瀏覽器更新屏幕之前會(huì)發(fā)生。這保證即使render()在這種情況下將被調(diào)用兩次,用戶(hù)也不會(huì)看到中間狀態(tài)。請(qǐng)謹(jǐn)慎使用此模式,因?yàn)檫@通常會(huì)導(dǎo)致性能問(wèn)題。但是,當(dāng)需要在渲染依賴(lài)于其大小或位置的東西之前測(cè)量DOM節(jié)點(diǎn)時(shí),可能需要類(lèi)似于模態(tài)和工具提示的情況。
componentWillReceiveProps(nextProps)
componentWillReceiveProps()在安裝的組件接收新的道具之前被調(diào)用。如果您需要在響應(yīng)更新?tīng)顟B(tài)托變化(例如,復(fù)位),你可以比較this.props和nextProps和執(zhí)行使用狀態(tài)轉(zhuǎn)換this.setState()在此方法。
請(qǐng)注意,即使道具尚未更改,React也可能會(huì)調(diào)用此方法,因此如果您只想處理更改,請(qǐng)務(wù)必比較當(dāng)前值和下一個(gè)值。父組件導(dǎo)致組件重新呈現(xiàn)時(shí),可能會(huì)發(fā)生這種情況。
componentWillReceiveProps()在安裝過(guò)程中,反應(yīng)不會(huì)與初始道具呼叫。只有在組件的某些道具可能更新時(shí)才會(huì)調(diào)用這個(gè)方法。調(diào)用this.setState()通常不會(huì)觸發(fā)componentWillReceiveProps()。
shouldComponentUpdate(nextProps,nextState)
使用shouldComponentUpdate()讓陣營(yíng)知道,如果一個(gè)組件的輸出不會(huì)受到州或道具的電流變化。默認(rèn)行為是在每次狀態(tài)更改時(shí)重新呈現(xiàn),在絕大多數(shù)情況下,您應(yīng)該依靠默認(rèn)行為。
shouldComponentUpdate()在渲染新的道具或狀態(tài)時(shí)被調(diào)用。默認(rèn)為true。此方法不用于初始渲染或何時(shí)forceUpdate()使用。
返回false不會(huì)阻止子組件在其狀態(tài)更改時(shí)重新呈現(xiàn)。
目前,如果shouldComponentUpdate()回報(bào)false,然后componentWillUpdate(),render()和componentDidUpdate()將不會(huì)被調(diào)用。請(qǐng)注意,將來(lái)React可能會(huì)被shouldComponentUpdate()視為提示而不是嚴(yán)格的指令,并且返回false可能仍會(huì)導(dǎo)致組件的重新呈現(xiàn)。
如果確定特定組件在分析后緩慢,則可以將其更改為從具有較淺支撐和狀態(tài)比較的React.PureComponent哪些實(shí)現(xiàn)中繼承shouldComponentUpdate()。如果你確信你想用手寫(xiě),你可以比較this.props,nextProps并this.state與nextState返回false告訴React更新可以跳過(guò)。
我們不建議這樣做深平等檢查或使用JSON.stringify()在shouldComponentUpdate()。這是非常低效的,會(huì)損害性能。
componentWillUpdate(nextProps,nextState)
componentWillUpdate()在渲染新的道具或狀態(tài)時(shí)立即被調(diào)用。使用這個(gè)機(jī)會(huì)在更新發(fā)生之前執(zhí)行準(zhǔn)備工作。這個(gè)方法不是為初始渲染調(diào)用的。
請(qǐng)注意,你不能this.setState()在這里打電話(huà);?你也不應(yīng)該做任何其他的事情(比如派遣一個(gè)Redux動(dòng)作),在componentWillUpdate()返回之前觸發(fā)一個(gè)React組件的更新。
如果您需要更新state以響應(yīng)props更改,請(qǐng)componentWillReceiveProps()改為使用。
注意
componentWillUpdate()如果shouldComponentUpdate()返回false,則不會(huì)被調(diào)用。
componentDidUpdate(prevProps,prevState)
componentDidUpdate()在更新發(fā)生后立即被調(diào)用。這個(gè)方法不是為初始渲染調(diào)用的。
當(dāng)組件更新時(shí),可以使用這個(gè)機(jī)會(huì)來(lái)操作DOM。只要你將目前的道具與以前的道具進(jìn)行比較,這也是一個(gè)很好的做網(wǎng)絡(luò)請(qǐng)求的地方(例如,如果道具沒(méi)有改變,可能不需要網(wǎng)絡(luò)請(qǐng)求)。
注意
componentDidUpdate()如果shouldComponentUpdate()返回false,則不會(huì)被調(diào)用。
componentWillUnmount()
componentWillUnmount()在組件被卸載并銷(xiāo)毀之前立即被調(diào)用。在這個(gè)方法中執(zhí)行任何必要的清理,例如使定時(shí)器無(wú)效,取消網(wǎng)絡(luò)請(qǐng)求,或者清理在其中創(chuàng)建的任何訂閱componentDidMount()。
componentDidCatch(error,info)
錯(cuò)誤邊界是React組件,可以在其子組件樹(shù)中的任何位置捕獲JavaScript錯(cuò)誤,記錄這些錯(cuò)誤,并顯示備用UI而不是崩潰的組件樹(shù)。錯(cuò)誤邊界在渲染,生命周期方法以及整個(gè)樹(shù)下的構(gòu)造函數(shù)中捕獲錯(cuò)誤。
如果一個(gè)類(lèi)組件定義了這個(gè)生命周期方法,它將成為一個(gè)錯(cuò)誤邊界。調(diào)用setState()它可以在下面的樹(shù)中捕獲未處理的JavaScript錯(cuò)誤,并顯示一個(gè)后備UI。只能使用錯(cuò)誤邊界從意外的異常中恢復(fù);?不要試圖將它們用于控制流程。
有關(guān)更多詳細(xì)信息,請(qǐng)參閱React 16中的錯(cuò)誤處理。
注意
錯(cuò)誤邊界只會(huì)捕獲樹(shù)中下面的組件中的錯(cuò)誤。錯(cuò)誤邊界本身不能捕獲錯(cuò)誤。
setState(updater[,callback])
setState()將更改排入組件狀態(tài),并告訴React該組件及其子組件需要使用更新的狀態(tài)重新呈現(xiàn)。這是用來(lái)更新用戶(hù)界面以響應(yīng)事件處理程序和服務(wù)器響應(yīng)的主要方法。
將其setState()看作是一個(gè)請(qǐng)求,而不是一個(gè)立即的命令來(lái)更新組件。為了獲得更好的感知性能,React可能會(huì)延遲它,然后一次更新幾個(gè)組件。React不保證立即應(yīng)用狀態(tài)更改。
setState()并不總是立即更新組件。它可能會(huì)批處理或推遲更新,直到更晚。這使得閱讀this.state正確后,setState()可能會(huì)陷入困境。相反,使用componentDidUpdate或setState回調(diào)(setState(updater, callback)),其中任何一個(gè)保證在應(yīng)用更新后觸發(fā)。如果您需要根據(jù)以前的狀態(tài)設(shè)置狀態(tài),請(qǐng)閱讀updater下面的參數(shù)。
setState()總是會(huì)導(dǎo)致重新呈現(xiàn),除非shouldComponentUpdate()得到回報(bào)false。如果正在使用可變對(duì)象并且無(wú)法實(shí)現(xiàn)條件呈現(xiàn)邏輯shouldComponentUpdate(),則setState()僅在新?tīng)顟B(tài)與先前狀態(tài)不同時(shí)調(diào)用將避免不必要的重新呈現(xiàn)。
第一個(gè)參數(shù)是updater帶簽名的函數(shù):
(prevState,props)=>stateChange
prevState是對(duì)以前的狀態(tài)的參考。它不應(yīng)該直接變異。相反,應(yīng)根據(jù)來(lái)自prevState和的輸入構(gòu)建新對(duì)象來(lái)表示更改props。例如,假設(shè)我們想通過(guò)以下方式增加一個(gè)狀態(tài)值props.step:
this.setState((prevState,props)=>{return{counter:prevState.counter+props.step};});
二者prevState并props通過(guò)更新功能接收保證是向上的更新。更新程序的輸出與淺層合并prevState。
第二個(gè)參數(shù)setState()是一個(gè)可執(zhí)行的回調(diào)函數(shù),將被執(zhí)行一次setState完成,并重新渲染組件。通常我們推薦使用componentDidUpdate()這樣的邏輯來(lái)代替。
你可以選擇傳遞一個(gè)對(duì)象作為第一個(gè)參數(shù)來(lái)setState()代替函數(shù):
setState(stateChange[,callback])
這會(huì)執(zhí)行stateChange到新?tīng)顟B(tài)的淺層合并,例如調(diào)整購(gòu)物車(chē)項(xiàng)目數(shù)量:
this.setState({quantity:2})
這種形式setState()也是異步的,并且在同一個(gè)周期內(nèi)的多個(gè)調(diào)用可以一起進(jìn)行批處理。例如,如果您嘗試在同一個(gè)周期內(nèi)多次增加一個(gè)項(xiàng)目數(shù)量,那么將導(dǎo)致等同于:
Object.assign(previousState,{quantity:state.quantity+1},{quantity:state.quantity+1},...)
隨后的調(diào)用將覆蓋同一周期中先前調(diào)用的值,因此數(shù)量只會(huì)增加一次。如果下一個(gè)狀態(tài)取決于之前的狀態(tài),我們建議使用更新函數(shù)形式,而不是:
this.setState((prevState)=>{return{quantity:prevState.quantity+1};});
有關(guān)更多詳細(xì)信息,請(qǐng)參閱州和生命周期指南。
component.forceUpdate(callback)
默認(rèn)情況下,當(dāng)組件的狀態(tài)或者道具改變時(shí),你的組件將重新渲染。如果你的render()方法依賴(lài)于其他數(shù)據(jù),你可以通過(guò)調(diào)用告訴React組件需要重新渲染forceUpdate()。
調(diào)用forceUpdate()將導(dǎo)致render()在組件上調(diào)用,跳過(guò)shouldComponentUpdate()。這將觸發(fā)子組件的正常生命周期方法,包括shouldComponentUpdate()每個(gè)子組件的方法。如果標(biāo)記更改,React將只會(huì)更新DOM。
通常情況下,你應(yīng)該盡量避免所有的使用forceUpdate()和只讀this.props和this.state中render()。
defaultProps可以被定義為組件類(lèi)本身的一個(gè)屬性,來(lái)設(shè)置該類(lèi)的默認(rèn)道具。這用于未定義的道具,但不適用于null道具。例如:
classCustomButtonextendsReact.Component{// ...}CustomButton.defaultProps={color:'blue'};
如果props.color沒(méi)有提供,它將被默認(rèn)設(shè)置為'blue':
render(){return;// props.color will be set to blue}
如果props.color設(shè)置為空,它將保持為空:
render(){return;// props.color will remain null}
該displayName字符串用于調(diào)試消息。通常,您不需要明確設(shè)置它,因?yàn)樗菑亩x組件的函數(shù)或類(lèi)的名稱(chēng)推斷出來(lái)的。如果要為調(diào)試目的顯示不同的名稱(chēng),或者要?jiǎng)?chuàng)建高階組件,則可能需要顯式設(shè)置它,有關(guān)詳細(xì)信息,請(qǐng)參閱包裝顯示名稱(chēng)以進(jìn)行簡(jiǎn)單調(diào)試。
this.props包含由該組件的調(diào)用者定義的道具。請(qǐng)參閱組件和道具以了解道具的介紹。
特別是,它this.props.children是一個(gè)特殊的道具,通常由JSX表達(dá)式中的子標(biāo)簽定義,而不是標(biāo)簽本身。
狀態(tài)包含特定于此組件的數(shù)據(jù),可能隨時(shí)間而改變。狀態(tài)是用戶(hù)定義的,它應(yīng)該是一個(gè)普通的JavaScript對(duì)象。
如果你不使用它render(),它不應(yīng)該在這個(gè)狀態(tài)。例如,您可以將計(jì)時(shí)器ID直接放在實(shí)例上。
有關(guān)狀態(tài)的更多信息,請(qǐng)參閱狀態(tài)和生命周期。
不要this.state直接變異,因?yàn)閟etState()之后的調(diào)用可能會(huì)取代你所做的變異。把this.state它看作是不可改變的。