React Context 的使用(高级)
context 上下文场景
- 公共信息(语音,主题)如何传递给每个组件?
- 用 props 太繁琐
- 用 redux 小题大做
一个更改 theme 配色的例子
js
import React from 'react';
// 创建 Context 填充默认值(任意一个 js 变量)
const ThemeContext = React.createContext('light');
// 底层组件 - 函数式组件
function ThemeLink(props) {
// const theme = this.context // 会报错,函数式组件没有实例,既没有 this
// 函数式组件可以使用 Consumer
return (
<ThemeContext.Consumer>
{(value) => <p>link's theme is {value}</p>}
</ThemeContext.Consumer>
);
}
// 底层组件 - class 组件
class ThemeButton extends React.Component {
// 指定 contextType 读取当前的 theme context
// static contextType = ThemeContext // 也可以用 ThemeButton.context
render() {
const theme = this.context; // React 会往上找到最近的 theme Provider,然后使用
return (
<div>
<p>button's theme is {theme}</p>
</div>
);
}
}
ThemeButton.contextType = ThemeContext; // 指定 contextType 读取当前 theme context
// 中间的组件再也不必指明往下传递 theme 了
function ToolBar(props) {
return (
<div>
<ThemeButton />
<ThemeLink />
</div>
);
}
// 最外层组件
class ContextDemo extends React.Component {
constructor(props) {
super(props);
this.state = {
theme: 'light',
};
}
render() {
// 数据提供者
return (
<ThemeContext.Provider value={this.state.theme}>
{/*里面的组件都可以消费数据*/}
<ToolBar />
<hr />
<button onClick={this.changeTheme}>change theme</button>
</ThemeContext.Provider>
);
}
changeTheme = () => {
this.setState({
theme: this.state.theme === 'light' ? 'dark' : 'light',
});
};
}
export default ContextDemo;