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: