React学习笔记之十: Context的使用方法

本文详细介绍了React中的Context API,包括其作用、基本用法以及如何在组件间共享状态。通过具体的代码示例展示了如何创建、提供及消费上下文,并讨论了动态Context的实现方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

10. React的上下文Context

1. Context的作用

组件间的参数传递是单向数据流(父->子),那么如果当子组件嵌套的很深层的时候,就会存在每一层嵌套的过程中都需要通过props进行传参,十分麻烦,要是在整个组件树中能有一个公共的“全局变量”那就好了, 每次我们需要相应的参数只要通过访问这个全局变量就可以达到我们想要的目的了,因此我们使用了上下文Context

2. Context三剑客
  • React.createContext(): 用于创建一个上下文
  • Provider: 用于为组件树提供特定的上下文
  • Consumer: 在组件树内获取特定的上下文内容

简单的Context使用方法


import React, { Component } from "react";

// 创建两个不同的上下文
const ComponentTreeParam = React.createContext();
// 这两个不同的上下文通过不同的属性名进行区分
const ComponentTreeParamV2 = React.createContext();

class Inner extends Component {
  list(elem) {
    console.log(elem);
    return elem.map((x, index) => (
      <div key={index}>
        姓名:{x.name} / 年龄: {x.age}
      </div>
    ));
  }

  render() {
    return (
      <div>
        // 直接这里的就是provider传入的参数
        // 然后返回一个jsx就可以插入dom中
        <ComponentTreeParam.Consumer>
          {elem => this.list(elem)}
        </ComponentTreeParam.Consumer>
        <div>恭喜发财</div>
        <ComponentTreeParamV2.Consumer>
          {elem => this.list(elem)}
        </ComponentTreeParamV2.Consumer>
        <br />
        // 将多个不同的context嵌套在一起使用
        <ComponentTreeParam.Consumer>
          {theme1 => {
            return (
              <ComponentTreeParamV2>
                {theme2 => {
                  return [...this.list(theme1), ...this.list(theme2)];
                }}
              </ComponentTreeParamV2>
            );
          }}
        </ComponentTreeParam.Consumer>
      </div>
    );
  }
}

class ToolBar extends Component {
  render() {
    return <Inner />;
  }
}

class Context extends Component {
  render() {
    const collections = [
      { name: "Zhangsan", age: 18 },
      { name: "LiSi", age: 20 }
    ];
    const collections2 = [
      { name: "Zhangsan", age: 35 },
      { name: "LiSi", age: 38 }
    ];
    return (
      // 将collection作为Provider的值传入该组件树
      <ComponentTreeParam.Provider value={collections}>
        <div>
         // 将collection2作为Provider的值传入该组件树
          <ComponentTreeParamV2.Provider value={collections2}>
            <ToolBar />
          </ComponentTreeParamV2.Provider>
        </div>
      </ComponentTreeParam.Provider>
    );
  }
}

export default Context;

动态Context的绑定


import React, { Component } from "react";

const style = {
  light: {
    background: "yellowgreen",
    color: "#ffdfd1"
  },
  dark: {
    background: "black",
    color: "white"
  }
};

const ThemeContext = React.createContext();

class Box extends Component {
  loadStyle(theme) {
    console.log(theme);
    return (
      <div>
        <div style={theme.color}>我会变色</div>
        <button onClick={theme.changeMethod}>我也可以帮你变色</button>
      </div>
    );
  }

  render() {
    return (
      <div>
        <ThemeContext.Consumer>
          // theme中包含了color和改变theme的方法
          // 调用相应的方法就可以改变主题了
          {(theme) => this.loadStyle(theme)}
        </ThemeContext.Consumer>
      </div>
    );
  }
}

class ToolBar extends Component {
  // 在中间组件中不用传递参数
  render() {
    return <Box />;
  }
}

class DynamicContext extends Component {
  constructor(props) {
    super(props);
    this.state = {
      colorTheme: style.light
    };
  }

  changeTheme() {
    console.log(this.state.colorTheme);
    this.setState(state => ({
      colorTheme: state.colorTheme === style.light ? style.dark : style.light
    }));
  }

  render() {
    const _this = this;
    // 通过绑定state到provider的value上,然后通过js动态变化state
    // 可以在根组件中定义使状态绑定的函数,这个方法就会在整个组件树中得到绑定
    return (
      <div>
        <ThemeContext.Provider
          value={{
            color: _this.state.colorTheme,
            changeMethod: _this.changeTheme.bind(_this)
          }}
        >
          <ToolBar />
        </ThemeContext.Provider>
        <button onClick={this.changeTheme.bind(this)}>变色吧</button>
      </div>
    );
  }
}

export default DynamicContext;

**Notes: **:

  1. Context主要用于一个组件树内的状态共享
  2. 先通过React.createContext()创建一个组件树的上下文,之后通过new一个上下文的实例, 然后通过Provider将该状态注入到子组件中,在子组件外部添加Consumer获得相应的上下文对象
  3. 调用注入value的方法,可以通过(param) => {}这个箭头函数注入,其中param就是我们注入的value值
  4. 可以嵌套注入,在最内部组件可以获得外部注入内容的所有参数
  5. 动态Context主要是可以将改变父组件状态的方法以参数的形式传入,这样可以在深层的组件中修改上级,上上级…的状态
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值