zoukankan      html  css  js  c++  java
  • React Context 的基本用法

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

    1. 用法

    React.createContext

    const MyContext = React.createContext(defaultValue);
    

    创建一个 Context 对象。当 React 渲染一个订阅了这个 Context 对象的组件,这个组件会从组件树中离自身最近的那个匹配的 Provider 中读取到当前的 context 值。

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

    Context.Provider

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

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

    Provider 接收一个 value 属性,传递给消费组件。一个 Provider 可以和多个消费组件有对应关系。多个 Provider 也可以嵌套使用,里层的会覆盖外层的数据。

    Context.Consumer

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

    这里,React 组件也可以订阅到 context 变更。这能让你在函数式组件中完成订阅 context。

    2. 实例应用

    image

    如图,在父组件中定义两个变量:fruit 和 count。子组件可以拿到父组件的fruit,子子组件可以拿到父组件的 fruit,并且可以改变count的值。

    实现步骤如下:

    2.1 新建文件 context.js

    创建一个Context 对象,并导出Provider和Consumer容器。

    import { createContext } from 'react'
    
    export const { Provider, Consumer } = createContext()
    
    

    2.2 新建父组件 index.js

    import React, { Component } from 'react'
    import { Provider } from './context' // 引入Provider
    import Son from './Son' // 引入子组件
    
    class Main extends Component {
      constructor(props) {
        super(props)
        this.state = {
          fruit: 'apple',
          count: 0,
        }
      }
    
      componentDidMount() {}
    
      getContext = () => {
        const { fruit, count } = this.state
        return {
          fruit,
          countUtil: {
            addCount: num => {
              this.setState({
                count: count + num,
              })
            },
            delCount: num => {
              this.setState({
                count: count - num,
              })
            },
          },
        }
      }
    
      render() {
        const { fruit, count } = this.state
        return (
          // Provider 容器, 其value接收一个getContext方法
          <Provider value={this.getContext()}>
            父组件 fruit = {fruit}, count = {count}
            <hr />
            <Son />
          </Provider>
        )
      }
    }
    
    export default Main
    
    

    2.3 新建子组件 Son.js

    import React, { Component } from 'react'
    import { Consumer } from './context' // 引入Consumer
    import GrandSon from './GrandSon' // 引入子子组件
    
    class Main extends Component {
      constructor(props) {
        super(props)
        this.state = {}
      }
    
      render() {
        return (
          // Consumer 容器,可以拿到父组件传递下来的 fruit 属性, 并可以展示对应的值
          <Consumer>
            {context => (
              <div>
                子组件 fruit={context.fruit}
                <hr />
                <GrandSon />
              </div>
            )}
          </Consumer>
        )
      }
    }
    
    export default Main
    
    

    2.4 新建子子组件 GrandSon.js

    import React, { Component } from 'react'
    import { Consumer } from './context' // 引入Consumer
    
    class Main extends Component {
      constructor(props) {
        super(props)
        this.state = {}
      }
    
      render() {
        return (
          // Consumer 容器,可以拿到父组件传递下来的 fruit 属性, 以及 countUtil对象下的 addCount 和 delCount 方法
          <Consumer>
            {context => (
              <div>
                子子组件 fruit={context.fruit}
                <br />
                <button type="button" onClick={() => context.countUtil.addCount(2)}>
                  加2
                </button>
                &nbsp;
                <button type="button" onClick={() => context.countUtil.delCount(3)}>
                  减3
                </button>
                <hr />
              </div>
            )}
          </Consumer>
        )
      }
    }
    
    export default Main
    
    
  • 相关阅读:
    centos8 将SSSD配置为使用LDAP并要求TLS身份验证
    Centos8 搭建 kafka2.8 .net5 简单使用kafka
    .net core 3.1 ActionFilter 拦截器 偶然 OnActionExecuting 中HttpContext.Session.Id 为空字符串 的问题
    Springboot根据不同环境加载对应的配置
    VMware Workstation12 安装 Centos8.3
    .net core json配置文件小结
    springboot mybatisplus createtime和updatetime自动填充
    .net core autofac依赖注入简洁版
    .Net Core 使用 redis 存储 session
    .Net Core 接入 RocketMQ
  • 原文地址:https://www.cnblogs.com/cckui/p/12738466.html
Copyright © 2011-2022 走看看