React16.8定义上下文的3种方式

1,852 阅读3分钟

一、Context(上下文)的认识

  • 1、在某些场景下,你想在整个组件树中传递数据,但却不想手动地在每一层传递属性。你可以直接在 React 中使用强大的contextAPI解决上述问题
  • 2、在一个典型的 React 应用中,数据是通过 props 属性自上而下(由父及子)进行传递的,但这种做法对于某些类型的属性而言是极其繁琐的(例如:地区偏好,UI 主题),这些属性是应用程序中许多组件都需要的。Context 提供了一种在组件之间共享此类值的方式,而不必显式地通过组件树的逐层传递 props
  • 3、使用过express或者koa框架的就会经常使用到上下文来在整个项目中传递数据的。
  • 本文中介绍react中几种常见的定义与使用上下文的方式,在react的生态圈中redux,react-router-dom等库中都使用到上下文来传递数据,理解好react上下文对今后看源码都有好处的。

二、在类组件中使用上下文的步骤

  • 1、创建一个上下文(多文件的情况下单独使用一个文件)

    import React, { Component } from 'react'
    
    // 创建一个上下文
    const ColorContext = React.createContext();
    
  • 2、在根组件中使用上下文的.Provider注入,需要传递的一个vaule的属性(需要传递到下面子组件的数据,子组件只获得到传递的数据)

    export default class ContextComponents1 extends Component {
      constructor(props) {
        super(props);
        this.state = {
          color: '#333',
        }
      }
      changeColor = (color) => {
        this.setState({ color });
      }
      render() {
        const { color } = this.state;
        return (
          <ColorContext.Provider value={{ color, changeColor: this.changeColor }}>
            {/* 只传递一个color和一个changeColor方法,子组件只能从上下文中获得到这两个属性/方法 */}
            <Header />
            <button onClick={() => this.changeColor('yellow')}>黄色</button>
            <button onClick={() => this.changeColor('green')}>绿色</button>
          </ColorContext.Provider>
        )
      }
    }
    
  • 3、在子组件中使用上下文

    class Header extends Component {
      // 如果子组件中需要使用上下文就定义该行
      static contextType = ColorContext;
      render() {
        console.log(this.context); // 可以获取到根组件中value中传递过来的color和changeColor方法
        return (
          <>
            <h1 style={{ color: this.context.color }}>我是header组件</h1>
            <Title />
          </>
        )
      }
    }
    

三、函数组件中使用上下文的方式

  • 1、定义上下文

    import React, { Component } from 'react';
    
    const ColorContext = React.createContext();
    
  • 2、定义根组件

    export default class ContextComponent2 extends Component {
      state = {
        color: '#333',
      }
      changeColor = (color) => {
        this.setState({ color })
      }
      render() {
        const { color } = this.state;
        return (
          <ColorContext.Provider value={{ color }}>
            <Header name={'header'} type={1} />
            <button onClick={() => this.changeColor('yellow')}>黄色</button>
            <button onClick={() => this.changeColor('green')}>绿色</button>
          </ColorContext.Provider>
        )
      }
    }
    
  • 3、在函数组件中使用

    function Header(props) {
      console.log(props, 'props属性')
      return (
        <ColorContext.Consumer>
          {
            value => {
              console.log(value, '上下文数据')
              return (<h1 style={{ color: value.color }}>我是header组件</h1>)
            }
          }
        </ColorContext.Consumer>
      )
    }
    

四、使用hooks新属性创建上下文

  • 1、创建一个上下文

    import React, { Component, useContext, useState } from 'react';
    const ColorContext = React.createContext();
    
  • 2、根组件

    export default () => {
      let [color, setColoer] = useState('#333');
    
      return (
        <ColorContext.Provider value={{ color }}>
          <Header />
          <button onClick={() => setColoer('yellow')}>黄色</button>
          <button onClick={() => setColoer('green')}>绿色</button>
        </ColorContext.Provider>
      )
    }
    
  • 3、在子组件中使用

    function Header(props) {
      let { color } = useContext(ColorContext);
      console.log(color, '上下文');
      return (
        <>
          <h1 style={{ color: color }}>我是header组件</h1>
        </>
      )
    }