Context 的作用
给整个组件树共享全局的数据
import React from "react";
import ReactDOM from "react-dom";
const CityContext = React.createContext({
name: "chengdu",
text: "成都",
});
class App extends React.Component {
state = {
cityInfo: {
name: "chengdu",
text: "成都",
},
};
changeCity(cityInfo) {
this.setState({
cityInfo,
});
}
render() {
return (
<CityContext.Provider value={this.state.cityInfo}>
<Header changeCity={this.changeCity.bind(this)} />
<span>{this.state.cityInfo.text}</span>
</CityContext.Provider>
);
}
}
class Header extends React.Component {
render() {
return <Selector changeCity={this.props.changeCity} />;
}
}
class Selector extends React.Component {
// 将上下文的类型指定为 CityContext
// this.context -> CityContext
// 向上找最近的 CityContext 的 Provider,并且取值 cityInfo
/*
contextType
class 的静态属性
在 ES3 就是 Selector.contextType
必需指向由 React.createContext 生成的 Context 对象
static contextType = CityContext;
给当前环境下的 context 重新指定引用
this 下的 context 为 CityContext
在生命周期函数和 render 函数中都可以访问
*/
static contextType = CityContext;
componentDidMount() {
console.log(this.context);
}
render() {
return (
<select
value={this.context.name}
onChange={(e) =>
this.props.changeCity({
name: e.target.value,
text: e.target[e.target.selectedIndex].text,
})
}
>
<option value="beijing">北京</option>
<option value="chengdu">成都</option>
<option value="hangzou">杭州</option>
<option value="shenzhen">深圳</option>
</select>
);
}
}
ReactDOM.render(<App />, document.getElementById("app"));
最适合的场景
杂乱无章的组件都需要同一些数据,
单纯为了不层层传递属性的话,Context 实际上是不合适的 (像纯函数般,不污染组件)
Context 弱点
弱化及污染组件的纯度,导致组件利用性降低。
组合的方法更为适合
import React from 'react';
import ReactDOM from 'react-dom';
class App extends React.Component {
constructor(props) {
super(props);
this.CitySelector = (
<Selector
cityData={this.state.cityData}
cityInfo={this.state.cityInfo}
changeCity={this.changeCity.bind(this)}
/>
);
}
state = {
headerTitle: '这是标题',
cityInfo: {
name: 'chengdu',
text: '成都',
},
cityData: [
{
name: 'beijing',
text: '北京',
},
{
name: 'chengdu',
text: '成都',
},
{
name: 'hangzou',
text: '杭州',
},
{
name: 'shenzhen',
text: '深圳',
},
],
};
changeCity(cityInfo) {
this.setState({
cityInfo,
});
}
render() {
return (
<>
<Header
text={this.state.headerTitle}
citySelector={this.CitySelector}
></Header>
<span>{this.state.cityInfo.text}</span>
</>
);
}
}
class Header extends React.Component {
render() {
return (
<header>
<h1>{this.props.text}</h1>
<div>{this.props.citySelector}</div>
</header>
);
}
}
class Selector extends React.Component {
render() {
return (
<select
defaultValue={this.props.cityInfo.name}
onChange={(e) => {
this.props.changeCity({
name: e.target.value,
text: e.target[e.target.selectedIndex].text,
});
}}
>
{this.props.cityData.map((item, index) => {
return (
<option value={item.name} key={index}>
{item.text}
</option>
);
})}
</select>
);
}
}
ReactDOM.render(<App />, document.getElementById('app'));