美文网首页
使用 context 进行跨组件传递数据

使用 context 进行跨组件传递数据

作者: 张_何 | 来源:发表于2022-05-10 16:07 被阅读0次
  • 由父组件向子组件传递数据的时候通常我们通过 props 来进行传递, 但是在父组件向子组件的子孙组件传递数据用 props 来进行传递时就比较麻烦,会产生冗余代码。那么有没有其他方式呢,今天我们就介绍一下使用 context 来传递,
Context
  • context 提供了一种在组件之间共享此类值的方式,而不必显示地通过组件树的逐层传递 props, context 设计目的是为了共享那些对于一个组件数而言是全局的数据,例如主题或者语言。
React.createContext
  • 创建一个需要共享的Context对象:
  • 如果一个组件订阅了Context,那么这个组件会从离自身最近的那个匹配的 Provider 中读取到当前的context值;
  • defaultValue是组件在顶层查找过程中没有找到对应的Provider,那么就使用默认值
Context.Provider
  • 每个 Context 对象都会返回一个 Provider React 组件,它允许消费组件订阅 context 的变化:
  • Provider 接收一个 value 属性,传递给消费组件;
  • 一个 Provider 可以和多个消费组件有对应关系;
  • 多个 Provider 也可以嵌套使用,里层的会覆盖外层的数据;
  • 当 Provider 的 value 值发生变化时,它内部的所有消费组件都会重新渲染;
Class.contextType
  • 挂载在 class 上的 contextType 属性会被重赋值为一个由 React.createContext() 创建的 Context 对象:
  • 这能让你使用 this.context 来消费最近 Context 上的那个值;
  • 你可以在任何生命周期中访问到它,包括 render 函数中;
Context.Consumer
  • 这里,React 组件也可以订阅到 context 变更。这能让你在 函数式组件 中完成订阅 context。
  • 这里需要 函数作为子元素(function as child)这种做法;
  • 这个函数接收当前的 context 值,返回一个 React 节点;
类组件使用 context 进行跨组件传递数据
具体步骤如下:
  • 首先,我们要使用 React.createContext 创造 context, 如下我们创造一个 UserContext ,这个名字自己定义,
const UserContext = React.createContext({ //设置初始值,如果没找到 Provider 就使用初始值
  nickname: "张三",
  level: 0
})
  • 然后使用 xxxContext.Provider 将父组件包裹, 注意 value 属性一定要给, 给它设置的值就是要传递的数据
<UserContext.Provider value={this.state}>
   <Profile />
</UserContext.Provider>
  • 再然后就是将UserContext赋值给要接收数据的孙组件的 contextType, ProfileHeader.contextType = UserContext

  • 最后,我们就可以在孙组件中使用 this,context.属性名来获取传过来的值了

<div>
   <h2>用户昵称: {this.context.nickname}</h2>
   <h2>用户等级: {this.context.level}</h2>
</div>

完整代码如下:

import React, { Component } from 'react';

// 创建Context对象
const UserContext = React.createContext({
  nickname: "张三",
  level: 0
})

class ProfileHeader extends Component {
  render() {
    return (
      <div>
        <h2>用户昵称: {this.context.nickname}</h2>
        <h2>用户等级: {this.context.level}</h2>
      </div>
    )
  }
}

ProfileHeader.contextType = UserContext;

function Profile(props) {
  return (
    <div>
      <ProfileHeader />
      <ul>
        <li>设置1</li>
        <li>设置2</li>
      </ul>
    </div>
  )
}

export default class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      nickname: "kobe",
      level: 99
    }
  }

  render() {
    return (
      <div>
        <UserContext.Provider value={this.state}>
          <Profile />
        </UserContext.Provider>
      </div>
    )
  }
}
  • 如果多个嵌套使用时,同样使用UserContext.Consumer,同函数式组件中的嵌套使用,使用UserContext.Consumer嵌套时,不需要再对 contextType 赋值了
class ProfileHeader extends Component {
  render(){
    return (
      <UserContext.Consumer>
        {
          value => {
            return (
              <ThemeContext.Consumer>
                {
                  theme => {
                    return (
                      <div>
                        <h2 style={{color: theme.color}}>用户昵称: {value.nickname}</h2>
                        <h2>用户等级: {value.level}</h2>
                        <h2>颜色: {theme.color}</h2>
                      </div>
                    )
                  }
                }
              </ThemeContext.Consumer>
            )
          }
        }
      </UserContext.Consumer>
    )
  }
}
函数式组件使用 context 进行跨组件传递数据
具体步骤如下:
  • 首先,我们要使用 React.createContext 创造 context, 如下我们创造一个 UserContext ,这个名字自己定义,
const UserContext = React.createContext({ //设置初始值
  nickname: "张三",
  level: 0
})
  • 然后使用 xxxContext.Provider 将父组件包裹, 注意 value 属性一定要给, 给它设置的值就是要传递的数据
<UserContext.Provider value={this.state}>
   <Profile />
</UserContext.Provider>
  • 最后在孙组件中使用UserContext.Consumer将传递的数据取出来
function ProfileHeader() {
  return (
    <UserContext.Consumer>
      {
        value => {
          return (
            <div>
              <h2>用户昵称: {value.nickname}</h2>
              <h2>用户等级: {value.level}</h2>
            </div>
          )
        }
      }
    </UserContext.Consumer>
  )
}
  • 如果是多个时嵌套使用即可,这么我们再增加一个ThemeContext来嵌套演示。
  • 创建 ThemeContext
const ThemeContext = React.createContext({
  color: "black"
})
  • UserContext和ThemeContext嵌套包裹父组件
<UserContext.Provider value={this.state}>
  <ThemeContext.Provider value={{ color: "red" }}>
    <Profile />
  </ThemeContext.Provider>
</UserContext.Provider>
  • 在孙组件中嵌套取值
function ProfileHeader() {
  return (
    <UserContext.Consumer>
      {
        value => {
          return (
            <ThemeContext.Consumer>
              {
                theme => {
                  return (
                    <div>
                      <h2 style={{color: theme.color}}>用户昵称: {value.nickname}</h2>
                      <h2>用户等级: {value.level}</h2>
                      <h2>颜色: {theme.color}</h2>
                    </div>
                  )
                }
              }
            </ThemeContext.Consumer>
          )
        }
      }
    </UserContext.Consumer>
  )
}
  • 完整代码如下:
import React, { Component } from 'react';

// 创建Context对象
const UserContext = React.createContext({
  nickname: "aaaa",
  level: -1
})

const ThemeContext = React.createContext({
  color: "black"
})

function ProfileHeader() {
  // jsx -> 嵌套的方式
  return (
    <UserContext.Consumer>
      {
        value => {
          return (
            <ThemeContext.Consumer>
              {
                theme => {
                  return (
                    <div>
                      <h2 style={{color: theme.color}}>用户昵称: {value.nickname}</h2>
                      <h2>用户等级: {value.level}</h2>
                      <h2>颜色: {theme.color}</h2>
                    </div>
                  )
                }
              }
            </ThemeContext.Consumer>
          )
        }
      }
    </UserContext.Consumer>
  )
}

function Profile(props) {
  return (
    <div>
      <ProfileHeader />
      <ul>
        <li>设置1</li>
        <li>设置2</li>
        <li>设置3</li>
        <li>设置4</li>
      </ul>
    </div>
  )
}

export default class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      nickname: "kobe",
      level: 99
    }
  }

  render() {
    return (
      <div>
        <UserContext.Provider value={this.state}>
          <ThemeContext.Provider value={{ color: "red" }}>
            <Profile />
          </ThemeContext.Provider>
        </UserContext.Provider>
      </div>
    )
  }
}

  • 注意由于类组件的contextType只能设置一个值,所以不能嵌套,后设置的会把前设置的覆盖掉

相关文章

  • 使用 context 进行跨组件传递数据

    由父组件向子组件传递数据的时候通常我们通过 props 来进行传递, 但是在父组件向子组件的子孙组件传递数据用 p...

  • React Context

    Context 在组件树进行数据传递全局数据 何时使用Context 共享哪些对于一个组件树而言是全局的数据 使用...

  • 关于react中的context

    一、context有什么用 当我们使用props进行组件中的数据传递时,假如祖先级组件的数据要传递至孙子级,这种情...

  • React Context

    1、作用 Context 提供了一个无需为每层组件手动添加 props,就能在组件树间进行数据传递的方法,实现跨级...

  • React Context使用过程

    组件多级传递 存在问题多级传递参数会是代码增多,不利于维护 使用 Context 类组件使用 Context 步骤...

  • React Context

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

  • Context - React跨组件访问数据的利器

    Context提供了一种跨组件访问数据的方法。它无需在组件树间逐层传递属性,也可以方便的访问其他组件的数据 在经典...

  • React.Context 的应用

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

  • 03-react-跨组件级通信Context

    react-跨组件级通信- Context 之前编写组件都是通过props或者state的方式来传递组件, 但组件...

  • react组件传递参数

    基本传参props 传递数据 在子组件中 传方法 在子组件使用 context 上下文传递参数 特点 引入的con...

网友评论

      本文标题:使用 context 进行跨组件传递数据

      本文链接:https://www.haomeiwen.com/subject/xmtkurtx.html