React 中最常用的組件的間的通信:數(shù)據(jù)是通過(guò)props屬性自上而下(由父?jìng)髯樱┮患?jí)一級(jí)進(jìn)行傳遞的,這種傳遞最常用但是最麻煩,有些情況也實(shí)現(xiàn)不了比如:你和爺爺有小秘密不想讓父?jìng)鬟f,想自己親口告訴你。Context 提供了一個(gè)無(wú)需為每層組件手動(dòng)添加 props,就能在組件樹(shù)間進(jìn)行數(shù)據(jù)傳遞的方法(無(wú)需顯示的通過(guò)組建樹(shù)逐層傳遞)。
如何使用Context
1.創(chuàng)建Context對(duì)象
const Context = React.createContext(defaultValue);
只有當(dāng)組件所處的樹(shù)中沒(méi)有匹配到 Provider 時(shí),其 defaultValue 參數(shù)才會(huì)生效。此默認(rèn)值有助于在不使用 Provider 包裝組件的情況下對(duì)組件進(jìn)行測(cè)試。注意:將 undefined 傳遞給 Provider 的 value 時(shí),消費(fèi)組件的 defaultValue 不會(huì)生效。比如:defaultValue:'zh'
2.創(chuàng)建Provider,傳遞value
<Context.Provider value={/* 某個(gè)值 */}>
當(dāng) Provider 的 value 值發(fā)生變化時(shí),它內(nèi)部的所有消費(fèi)組件都會(huì)重新渲染。
3.子組件消費(fèi)value(有三種途徑:contextType,useContext,Consumer)
這三種的區(qū)別:
contextType:只能用類組件,只能訂閱單一的context;useContext:函數(shù)組件(自定hook);Consumer:不限制函數(shù)組件還是類組件使用
注意事項(xiàng)
因?yàn)?context 會(huì)根據(jù)引用標(biāo)識(shí)來(lái)決定何時(shí)進(jìn)行渲染(本質(zhì)上是 value 屬性值的淺比較),所以這里可能存在一些陷阱,當(dāng) provider 的父組件進(jìn)行重渲染時(shí),可能會(huì)在 consumers 組件中觸發(fā)意外的渲染。舉個(gè)例子,當(dāng)每一次 Provider 重渲染時(shí),以下的代碼會(huì)重渲染所有下面的 consumers 組件,因?yàn)?value 屬性總是被賦值為新的對(duì)象:
class App extends React.Component {
render() {
return (
<Context.Provider value={{something: 'something'}}>
<Toolbar />
</Context.Provider>
);
}
}
為了防止這種情況,將 value 狀態(tài)提升到父節(jié)點(diǎn)的 state 里:
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
value: {something: 'something'},
};
}
render() {
return (
<Context.Provider value={this.state.value}>
<Toolbar />
</Context.Provider>
);
}
}
總結(jié):如果value是個(gè)對(duì)象記得要提出來(lái),如果是 string,number,可以不用提,兩個(gè)對(duì)象相比一直是false,那么組件每次都會(huì)刷新。