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
    
    
  • 相关阅读:
    Node.js Event Loop 的理解 Timers,process.nextTick()
    Ajax关于readyState(状态值)和status(状态码)的研究
    原生 JavaScript 实现 AJAX、JSONP
    Python selenium.webdriver.chrome.options.Options() Examples
    【python】统一转换日期格式dateutil.parser.parse
    python读取doc
    大规模爬虫流程总结
    如何巧妙的利用selenium和requests组合来进行操作需要登录的页面
    使用pandas进行数据清洗
    twilio打电话和发短信
  • 原文地址:https://www.cnblogs.com/cckui/p/12738466.html
Copyright © 2011-2022 走看看