React中的Context使用方法

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

React.createContext

const MyContext = React.createContext(defaultValue);

只有当组件所处的树中没有匹配到 Provider 时,其 defaultValue 参数才会生效。这有助于在不使用 Provider 包装组件的情况下对组件进行测试。注意:将 undefined 传递给 Provider 时,消费组件的 defaultValue 不会生效。

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

class App extends Component {
  render() {
    return (
      <div>
        <Toolbar />
      </div>
    );
  }
}

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

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

export default App;

Context.Provider

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

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

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

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

export default App;

Provider 接收一个 value 属性,传递给消费组件。

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() {
    console.log(this.context) // dark
    return (
      <button>{this.context}</button>
    );
  }
}

export default App;

一个 Provider 可以和多个消费组件有对应关系。

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

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

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


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

export default App;

多个 Provider 也可以嵌套使用,里层的会覆盖外层的数据。

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

class App extends Component {
  render() {
    return (
      <div>
        <ThemeContext.Provider value='dark1'>
          <Toolbar />
          <ThemeContext.Provider value='dark2'>
            <Toolbar />
          </ThemeContext.Provider>
        </ThemeContext.Provider>
      </div>
    );
  }
}

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


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

export default App;

Providervalue 值发生变化时,它内部的所有消费组件都会重新渲染。Provider 及其内部 consumer 组件都不受制于 shouldComponentUpdate 函数

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

class App extends Component {
  constructor (props) {
    super(props);
    this.state = {
      theme: 'dark' 
    }
  }
  change = () => {
    this.setState({
      theme: 'light'
    })
  }
  render() {
    return (
      <div>
        <ThemeContext.Provider value={this.state.theme}>
          <Toolbar />
        </ThemeContext.Provider>
        <button onClick={this.change}>change</button>
      </div>
    );
  }
}

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


class ThemeButton extends Component {
  static contextType = ThemeContext
  shouldComponentUpdate () {
    console.log('无法控制组件')
    return false
  }
  render() {
    return (
      <button>{this.context}</button>
    );
  }
}

export default App;

挂载在 class 上的 contextType 属性会被重赋值为一个由 React.createContext() 创建的 Context 对象。这能让你使用 this.context 来消费最近 Context 上的那个值。你可以在任何生命周期中访问到它,包括 render 函数中。

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

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

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


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

export default App;

Context.Consumer

这能让你在函数式组件中完成订阅 context。这需要函数作为子元素(function as a child)这种做法。这个函数接收当前的 context 值,返回一个 React 节点。传递给函数的 value 值等同于往上组件树离这个 context 最近的 Provider 提供的 value 值。如果没有对应的 Providervalue 参数等同于传递给 createContext()defaultValue

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

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

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

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

export default App;

你可能感兴趣的:(react)