Context 提供了一个无需为每层组件手动添加 props,就能在组件树间进行数据传递的方法。

import React, { Component } from 'react';

class App extends Component {
  render() {
    return (
      <Toolbar theme="dark" />
    );
  }
}

function Toolbar (props) {
  return (
    <div>
      <ThemeButton theme={props.theme} />
    </div>
  )
}

class ThemeButton extends Component {
  render() {
    return (
      <button>{this.props.theme}</button>
    );
  }
}

export default App;

旧版本的使用

import React, { Component } from 'react';
import PropTypes from 'prop-types';

class App extends Component {
  static childContextTypes = {
    theme: PropTypes.string
  }
  getChildContext () {
    return {
      theme: 'dark'
    }
  }
  render() {
    return (
      <Toolbar />
    );
  }
}

function Toolbar (props) {
  return (
    <div>
      <ThemeButton />
    </div>
  )
}

class ThemeButton extends Component {
  static contextTypes = {
    theme: PropTypes.string
  }
  render() {
    return (
      <button>{this.context.theme}</button>
    );
  }
}

export default App;

新版本的使用

import React, { Component } from 'react';
const ThemeContext = React.createContext('light');

class App extends Component {
  render() {
    return (
      <ThemeContext.Provider value="dark">
        <Toolbar />
      </ThemeContext.Provider>
    );
  }
}

function Toolbar (props) {
  return (
    <div>
      <ThemeButton />
    </div>
  )
}

class ThemeButton extends Component {
  static contextType = ThemeContext
  render() {
    return (
      <button>{this.context}</button>
    );
  }
}

export default App;

这能让你在函数式组件中完成订阅 context。

import React, { Component } from 'react';
import PropTypes from 'prop-types';
const ThemeContext = React.createContext('light');

class App extends Component {
  render() {
    return (
      <ThemeContext.Provider value="dark">
        <Toolbar />
      </ThemeContext.Provider>
    );
  }
}

function Toolbar (props) {
  return (
    <div>
      <ThemeButton />
    </div>
  )
}

function ThemeButton () {
  return (
    <ThemeContext.Consumer>
      {
        value => (
          <button>{value}</button>
        )
      }
    </ThemeContext.Consumer>
  )
}

export default App;