Context是 react中爲了不在不一樣層級組件中逐層傳遞props的產物,在沒有Context的時候父組件向子組件傳遞props屬性只能在組件樹上自上而下進行傳遞,可是有些屬性並非組件樹的每層節點都有相同的需求,這樣咱們再這樣逐層傳遞props就顯得代碼很繁瑣笨重。css
使用react.createContext(defulData)能夠經過建立一個ContextObject,在某個組件中調用ContextObject.Provider同時能夠設置新的value = newData覆蓋掉defulData共享到下面的全部子組件,須要ContextObject共享出來的數據的子組件能夠經過static contextType = ContextObject接收到data,使用this.context便可調用datareact
不少不一樣層級的組件須要訪問一樣的數據,因此若是咱們只是想避免層層傳遞一些屬性,那麼咱們還有更好的選擇: 組合組件api
React.createContext(defaultValue)
建立一個Context對象,defaultValue是默認參數,在一個組件中能夠調用這個對象的ProviderAPI,而且設置新的參數:數組
可是若是沒有對應的Context.Provider相匹配,那麼組件樹上的全部組件均可以收到這個Context對象發出 的defaultValue;app
同時能夠調用Context的ConsumerAPI能夠用來接受到Context的值,而且根據這個值渲染組件:dom
Context.Provider & Context.Comsumeride
<MyContext.Provider value={ variableValue }>能夠容許消費組件訂閱到variableValue 值的變化,也就是說消費組件能夠根據variableValue值的變化而變化,variableValue的值咱們能夠定義一個事件來控制改變;函數
利用Context.Consumer API 可讓咱們即便是在函數式組件也能夠訂閱到 Context的值;性能
這種方法須要一個函數做爲子元素,函數接收當前的context值,並返回一個 React 節點。this
傳遞給函數的 value 值等價於組件樹上方離這個 context 最近的 Provider 提供的 variableValue值。若是沒有對應的 Provider,value 參數等同於傳遞給 createContext() 的 defaultValue。
當Provider的 variableValue值發生變化時,它內部的全部消費組件都會從新渲染。
Class.contextType
掛載在 class 上的 contextType 屬性會被重賦值爲一個由 React.createContext() 建立的 Context 對象。此屬性能讓你使用 this.context 來消費最近 Context 上的那個值。你能夠在任何生命週期中訪問到它,包括 render 函數中。
注: 從文檔的字面意思,Class.contextType是類組件特有的API,因此函數式組件只能使用 Context.Consumer來訪問 Context對象的值,咱們能夠來試一下類組件和函數式組件的API:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
// 建立 Context 對象
const MyContext = React.createContext(0)
// App組件 渲染 Context 對象
class App extends React.Component {
constructor(props){
super(props);
this.state = {
variableValue : 0
}
this.handleChange = () => {
this.setState(state => ({
variableValue: state.variableValue + 1
})
)
}
}
render(){
return (
// 調用 Context.Provider, 設置可讓Consumer組件監聽變化的 value 值
<MyContext.Provider value = {this.state.variableValue}>
<Context_consumer changeValue = {this.handleChange} />
<br/>
<Context_contextType changeValue = {this.handleChange} />
<br />
<Func_Consumer changeValue = {this.handleChange} />
<br />
<func_contextType changeValue = {this.handleChange} />
</MyContext.Provider>
)
}
}
// Class & Consumer 消費組件
class Context_consumer extends React.Component{
render(){
return (
<MyContext.Consumer>
{value =>
<button onClick={this.props.changeValue} >
Add Class_consumer:{value}
</button>
}
</MyContext.Consumer>
)
}
}
// Class & contextType 的消費組件
class Context_contextType extends React.Component{
render(){
let value = this.context
return (
<button onClick={this.props.changeValue} >
Add Class_contextType:{value}
</button>
)
}
};
Context_contextType.contextType = MyContext;
// 函數組件 & Consumer
function Func_Consumer (props) {
return (
<MyContext.Consumer>
{value =>
<button onClick={props.changeValue} >
Add Func_consumer:{value}
</button>
}
</MyContext.Consumer>
)
}
// 函數組件 & contextType
function func_contextType (props) {
let value = this.context
return (
<button onClick={props.changeValue} >
Add func_contextType:{value}
</button>
)
}
func_contextType.contextType = MyContext;
ReactDOM.render(
<App className = 'app'/>
,
document.getElementById('root')
);
運行結果:
除了func_contextType組件以外其餘組件均可以正常運行
http://www.ssnd.com.cn 化妝品OEM代加工
Context.displayName
context 對象接受一個名爲 displayName 的 property,類型爲字符串。React DevTools 使用該字符串來肯定 context 要顯示的內容。
示例,下述組件在 DevTools 中將顯示爲 MyDisplayName: