Context是局部的全局变量,使用Context避免通过中间元素传递props
import "./styles.css";
import React from 'react'
// 创建一个context
const ThemeContext = React.createContext('light');
function F1(){
return (
<div>1
<F2/>
</div>
)
}
function F2(){
return (
<div>2
<F3/>
</div>
)
}
function F3(){
return (
<div>3
{/* 用Consumer包住组件,函数形式传值 */}
<ThemeContext.Consumer>
{(n)=><F4 n={n}/>}
</ThemeContext.Consumer>
</div>
)
}
function F4(props){
return (
<div>4, {props.n}</div>
)
}
export default function App() {
return (
<div className="App">
{/* 用Provider包住组件,并传递value */}
<ThemeContext.Provider value='100'>
<F1/>
</ThemeContext.Provider>
</div>
);
}
consumer通过props.children调用传递的函数
function Consumer(props){
let x=100
props.children(x)
return (
<div>hello</div>
)
}
export default function App() {
return (
<Consumer>
{(n)=>{console.log('我被调用了', 100)}}
</Consumer>
);
}
实践:点击按钮更换CSS样式
(在codesandbox中编辑App.js文件)
import "./styles.css";
import React from "react";
const themeContext = new React.createContext();
function Box(props) {
return <div className={props.theme}>{props.children}</div>; /* props.children获得子组件 */
}
function Button() {
return <button>点我</button>;
}
function Input() {
return <input />;
}
export default class App extends React.Component {
constructor() {
super();
this.state = {
theme: "red"
};
}
changeTheme() {
if (this.state.theme === "red") {
this.setState({ theme: "green" });
} else {
this.setState({ theme: "red" });
}
}
render() {
return (
<div>
<button onClick={this.changeTheme.bind(this)}>换肤</button>
<themeContext.Provider value={this.state.theme}> {/* 将值传给value */}
{/* 哪个组件要用value,就用Consumer包起来,通过箭头函数形式传参数 */}
<themeContext.Consumer>
{/* 注意=>右边没有花括号 */}
{theme=><div>
<Box theme={theme}><Button/></Box>
<Box theme={theme}><Input/></Box>
</div>}
</themeContext.Consumer>
</themeContext.Provider>
</div>
);
}
}