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/*contextTypeclass 的静态属性在 ES3 就是 Selector.contextType必需指向由 React.createContext 生成的 Context 对象static contextType = CityContext;给当前环境下的 context 重新指定引用this 下的 context 为 CityContext在生命周期函数和 render 函数中都可以访问*/static contextType = CityContext;componentDidMount() {console.log(this.context);}render() {return (<selectvalue={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 = (<SelectorcityData={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 (<><Headertext={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 (<selectdefaultValue={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'));
