React context 的使用方法

通常在 React 组件中,我们会使用 props 来自上而下(父传子)的传递属性。但是当组件层级太深时,或者某些属性是应用中很多组件都需要使用的,比如UI主题等,使用传统的 props 来处理就会显得非常麻烦。而 Context 就提供了一种组件间信息共享的解决方式,从而避免了通过 props 的逐层传递。

1. 生产者

React.createContext:创建一个 Context 对象;

const MyContext = React.createContext(defaultValue);

Context.Provider:每个 Context 对象都会返回一个 Provider React 组件,它允许消费组件订阅 context 的变化。

<MyContext.Provider value={/* 某个值 */}>
    <MyClass />
</MyContext.Provider>

2. 消费者

Class 组件消费

import React from 'react'
class MyClass extends React.Component {
  render() {
    let value = this.context;
    /* 基于 MyContext 组件的值进行渲染 */
  }
}
MyClass.contextType = MyContext;

函数组件使用 Consumer 消费

<MyContext.Consumer>
  {value => /* 基于 context 值进行渲染*/}
</MyContext.Consumer>

函数组件使用 useContext 来消费

const value = useContext(MyContext);

示例

const themes = {
  light: {
    foreground: "#000000",
    background: "#eeeeee"
  },
  dark: {
    foreground: "#ffffff",
    background: "#222222"
  }
};
// 定义 Context
const ThemeContext = React.createContext(themes.light);

function App() {
  return (
    // 使用 ThemeContext.Provider 组件进行包裹,子组件就能消费 ThemeContext
    <ThemeContext.Provider value={themes.dark}>
      <Toolbar />
    </ThemeContext.Provider>
  );
}

function Toolbar(props) {
  return (
    <div>
      <ThemedButtonFunc />
      <ThemedButtonFuncConsumer />
      <MyClass />
    </div>
  );
}

// 函数组件使用 useContext 进行消费
function ThemedButtonFunc() {
  const theme = useContext(ThemeContext); 
  return (
    <button style={
   
   { background: theme.background, color: theme.foreground }}>
      I am styled by theme context!
    </button>
  );
}

// 函数组件使用 ThemeContext.Consumer 进行消费
function ThemedButtonFuncConsumer() {
  return (
    <ThemeContext.Consumer>
      {
        theme => (
          <button style={
   
   { background: theme.background, color: theme.foreground }}>
            I am styled by theme context!
          </button>
        )
      }
    </ThemeContext.Consumer>
  );
}

// class 组件使用 contextType 进行消费
class MyClass extends React.Component {
  render() {
    let theme = this.context;
    /* 基于 MyContext 组件的值进行渲染 */
    return (
      <button style={
   
   { background: theme.background, color: theme.foreground }}>
        I am styled by theme context!
      </button>
    );
  }
}
MyClass.contextType = ThemeContext;

猜你喜欢

转载自blog.csdn.net/josavion/article/details/113243927