Skip to content

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;

基于 MIT 许可发布