Context
在組件樹進(jìn)行數(shù)據(jù)傳遞全局?jǐn)?shù)據(jù)
何時(shí)使用Context
- 共享哪些對(duì)于一個(gè)組件樹而言是全局的數(shù)據(jù)
- 使用Context庙洼,避免通過(guò)中間元素傳遞props
使用Context的注意
如果只是想要避免層層傳遞一些屬性顿痪,組件組合是更好的方案
一種無(wú)需context的解決方案是將組件自身直接傳遞下去镊辕,而不是傳遞過(guò)多的props
Context是將數(shù)據(jù)向組件樹下的所有組件進(jìn)行廣播,所有組件都能訪問(wèn)到這些數(shù)據(jù)蚁袭,也能訪問(wèn)到后續(xù)的數(shù)據(jù)更新
API
React.createContext
const MyContext = React.createContext(defaultValue);
只有當(dāng)所處的組件樹中沒(méi)有匹配搭配Provider時(shí)征懈,defaultValue才會(huì)生效。
Context.Provider
<MyContext.Provider value={/* 某個(gè)值 */}>
- 多個(gè)Provider可以嵌套使用揩悄,里面的會(huì)覆蓋外面的值
- 當(dāng)Provider的value值發(fā)生變化時(shí)受裹,它內(nèi)部的所有消費(fèi)組件都會(huì)重新渲染
Class.contextType
class MyClass extends React.Component {
componentDidMount() {
let value = this.context;
/* 在組件掛載完成后,使用 MyContext 組件的值來(lái)執(zhí)行一些有副作用的操作 */
}
componentDidUpdate() {
let value = this.context;
/* ... */
}
componentWillUnmount() {
let value = this.context;
/* ... */
}
render() {
let value = this.context;
/* 基于 MyContext 組件的值進(jìn)行渲染 */
}
}
MyClass.contextType = MyContext;
//新語(yǔ)法
class MyClass extends React.Component {
static contextType = MyContext;
render() {
let value = this.context;
/* 基于這個(gè)值進(jìn)行渲染工作 */
}
}
- 使用this.context來(lái)消費(fèi)最近Context上的那個(gè)值
- 可以在任何生命周期中訪問(wèn)到它虏束,包括render()中
Context.Consumer
<MyContext.Consumer>
{value => /* 基于 context 值進(jìn)行渲染*/}
</MyContext.Consumer>
在函數(shù)式組件中完成訂閱context
這個(gè)函數(shù)接收當(dāng)前的content值,返回一個(gè)react節(jié)點(diǎn)
Context.displayName
設(shè)置在DevTools中將顯示的內(nèi)容
動(dòng)態(tài)Context
- 在Provider內(nèi)部的組件厦章,使用state中的值
- 外部的組件使用React.createContext時(shí)的默認(rèn)值
在嵌套組件中更新Context
通過(guò)context傳遞一個(gè)函數(shù)镇匀,使得consumers組件更新context
消費(fèi)多個(gè)Context
為了確保 context 快速進(jìn)行重渲染,React 需要使每一個(gè) consumers 組件的 context 在組件樹中成為一個(gè)單獨(dú)的節(jié)點(diǎn)袜啃。