contextType
- 指定context类型为创建的上下文,此时不需要用Consumer组件包裹,使用this.context即可访问
- 会向上找最近的上下文并取值
- 最适合的场景:杂乱无章的组件都需要同一些数据;若单纯为了不层层传递属性,使用context是不合适的
- Context弱点:弱化及污染组件的纯度,导致组件复用性降低
- 使用组合组件(组件嵌套),则不需要使用context
使用context
const CityContext = React.createContext({
value: 'hongkong',
label: '香港'
})
class Content extends React.Component {
render() {
return (
<h1>{this.props.label}</h1>
)
}
}
class Selector extends React.Component {
static contextType = CityContext
render() {
return (
<>
<select
value={this.context.name}
onChange={(e) => {
this.props.changeCity({
value: e.target.value,
label: e.target[e.target.selectedIndex].label
})
}}>
<option value="hongkong">香港</option>
<option value="hangzhou">杭州</option>
<option value="fujian">福建</option>
<option value="manila">马尼拉</option>
</select>
</>
)
}
}
class Main extends React.Component {
state = {
cityInfo: {
value: 'hongkong',
label: '香港'
}
}
changeCity = (obj) => {
this.setState({
cityInfo: obj
})
}
render() {
return (
<>
<CityContext.Provider value={this.state.cityInfo}>
<Content label={this.state.cityInfo.label} />
<Selector changeCity={this.changeCity} />
</CityContext.Provider>
</>
)
}
}
ReactDOM.render(<Main />, document.getElementById('app'))
使用组合组件
class Content extends React.Component {
render() {
return (
<div>
<h1>{this.props.label}</h1>
<div>{this.props.selector}</div>
</div>
)
}
}
class Selector extends React.Component {
render() {
return (
<>
<select
value={this.props.dataForSelector.name}
onChange={(e) => {
this.props.changeCity({
value: e.target.value,
label: e.target[e.target.selectedIndex].label
})
}}>
<option value="hongkong">香港</option>
<option value="hangzhou">杭州</option>
<option value="fujian">福建</option>
<option value="manila">马尼拉</option>
</select>
</>
)
}
}
class Main extends React.Component {
state = {
cityInfo: {
value: 'hongkong',
label: '香港'
}
}
changeCity = (obj) => {
this.setState({
cityInfo: obj
})
}
render() {
return (
<>
<Content label={this.state.cityInfo.label}
selector={<Selector changeCity={this.changeCity} dataForSelector={this.state.cityInfo} />} />
{}
</>
)
}
}
ReactDOM.render(<Main />, document.getElementById('app'))