Context 設計目的是爲了共享那些對於一個組件樹而言是「全局」的數據,例如當前認證的用戶、主題或首選語言。算法
// Context 可讓咱們無須明確地傳遍每個組件,就能將值深刻傳遞進組件樹。 // 爲當前的 theme 建立一個 context(「light」爲默認值)。 const ThemeContext = React.createContext('light'); class App extends React.Component { render() { // 使用一個 Provider 來將當前的 theme 傳遞給如下的組件樹。 // 不管多深,任何組件都能讀取這個值。 // 在這個例子中,咱們將 「dark」 做爲當前的值傳遞下去。 return ( <ThemeContext.Provider value="dark"> <Toolbar /> </ThemeContext.Provider> ); } } // 中間的組件不再必指明往下傳遞 theme 了。 function Toolbar(props) { return ( <div> <ThemedButton /> </div> ); } class ThemedButton extends React.Component { // 指定 contextType 讀取當前的 theme context。 // React 會往上找到最近的 theme Provider,而後使用它的值。 // 在這個例子中,當前的 theme 值爲 「dark」。 static contextType = ThemeContext; render() { return <Button theme={this.context} />; } }
Context 主要應用場景在於不少不一樣層級的組件須要訪問一樣一些的數據。請謹慎使用,由於這會使得組件的複用性變差。ide
建立一個 Context
對象。當 React 渲染一個訂閱了這個 Context
對象的組件,這個組件會從組件樹中離自身最近的那個匹配的 Provider
中讀取到當前的 context
值。函數
只有當組件所處的樹中沒有匹配到 Provider
時,其 defaultValue
參數纔會生效。這有助於在不使用 Provider
包裝組件的狀況下對組件進行測試。注意:將 undefined
傳遞給 Provider
時,消費組件的 defaultValue
不會生效。測試
const MyContext = React.createContext(defaultValue);
每一個 Context
對象都會返回一個 Provider React
組件,它容許消費組件訂閱 context
的變化。this
Provider
接收一個 value
屬性,傳遞給消費組件。一個 Provider
能夠和多個消費組件有對應關係。多個 Provider
也能夠嵌套使用,裏層的會覆蓋外層的數據。設計
當 Provider
的 value
值發生變化時,它內部的全部消費組件都會從新渲染。Provider
及其內部 consumer
組件都不受制於 shouldComponentUpdate
函數,所以當 consumer
組件在其祖先組件退出更新的狀況下也能更新。code
經過新舊值檢測來肯定變化,使用了與 Object.is 相同的算法。對象
<MyContext.Provider value={/* 某個值 */}>
這須要函數做爲子元素(function as a child
)這種作法。這個函數接收當前的 context
值,返回一個 React
節點。傳遞給函數的 value
值等同於往上組件樹離這個 context
最近的 Provider
提供的 value
值。若是沒有對應的 Provider
,value
參數等同於傳遞給 createContext()
的 defaultValue
。io
<MyContext.Consumer> {value => /* 基於 context 值進行渲染*/} </MyContext.Consumer>