zoukankan      html  css  js  c++  java
  • 父组件向孙子组件传值(Context)特性

    引言

    在我们React组件开发中,当一个父组件的想要往自己的子孙组件传值的时候,可以使用 props属性,但是其每一个子组件,都要向下传递数据,这样造成的数据的耦合性,所以在 React 官方文档中 提供了 context特性来解决,这个问题。

    父子组件之间的通信

    我们先看一下React中,父子组件通信的机制,父子组件的通信是通过props进行数据的传递:

    1. 父组件向子组件传递数据(状态)时,是在调用子组件的时候通过参数传递给子组件,子组件通过this.props进行接收;
    2. 子组件如果更改父组件的一些属性,则是通过父组件定义的方法来传递给子组件,子组件调用更改;
    3. 如果父组件想要更改子组件的一些状态时,通过ref进行标记,可以获取子组件的所有信息,从而调用子组件的方法和值;

    但是,如果层级很多呢,是否需要多个props进行逐层的传递?答案是否定的,React的advanced(高级)中指出了context,优雅的解决这个问题。

    好的,接下来我们来介绍一下这个特性Context

    我们知道,在JS中context指的是函数的执行上下文,函数被调用时,this指向谁,谁就是当前的执行上下文;

    1. react中的context是什么呢?官方文档给出:
      • Context 通过组件树提供了一个传递数据的方法,从而避免了在每一个层级手动的传递 props 属性。

    文档也没具体给出context到底是什么,而是告诉我们context能干什么,也就是说,如果我们不想通过props实现组件树的逐层传递数据,则可以使用context实现跨层级进行数据传递!

    如何使用 Context 呢?

    context api给出三个概念:React.createContext()、Provider、Consumer;

    1. React.createContext()
    这个方法用来创建context对象,并包含Provider、Consumer两个组件 <Provider />、<Consumer />
    
    const {Provider, Consumer} = React.createContext();
    
    1. Provider
    数据的生产者,通过value属性接收存储的公共状态,来传递给子组件或后代组件
    
    eg:
    
    <Provider value={/* some value */}>
    
    1. Consumer
    数据的消费者,通过订阅Provider传入的context的值,来实时更新当前组件的状态
    
    eg: 
    
    <Consumer>
      {value => /* render something based on the context value */}
    </Consumer>
    
    

    值得一提的是每当Provider的值发生改变时, 作为Provider后代的所有Consumers都会重新渲染
    props单向数据流动:

    如果觉得Props传递数据很繁琐,可以采用context,进行跨组件传递数据

    再最外层的组件上,通过生产者Provider组件进行包裹,并存储共享数据到value中,当然可以是任何数据类型。后带需要用到共享数据的组件均可通过Consumer进行数据获取

    代码演示

    
    import React from 'react'
    import ReactDOM from 'react-dom'
    
    // 创建一个 textcont 特性的
    const {Provider,Consumer} = React.createContext('顶顶顶')
    
    class Person extends React.Component{
        constructor(props){
            super(props)
    
    
            this.state = {
                color : 'red'
            }
        }
    
    
        render(){
            return (
                     <Provider value={this.state.color}>
                            <h1>我是父组件</h1>
                            <Son></Son>
                    </Provider>
            );
        }
    }
    
    
    
    class Son extends Person{
        render(){
            return <div>
                <h3>我是子组件</h3>
                <Son1></Son1>
            </div>
        }
    }
    
    
    
    class Son1 extends Son{
        render(){
            return (
                <Consumer>
                    {
                        (color) => <div>
                            <h6 style={{color}}>我是孙子组件-----{color}</h6>
                        </div>
                    }
                </Consumer>
            );
            
        }
    }
    
    
    
    ReactDOM.render(<div>
        <Person></Person>
    </div>,document.getElementById('app'))
    
    

    参考作品出处:
    https://segmentfault.com/a/1190000017758300

  • 相关阅读:
    存储过程和触发器
    RuPengWang项目
    短信验证
    Lucene.Net 站内搜索
    Quartz 定时任务(含Redis)
    网上支付(支付宝/银联)
    iOS 图片选择的路径处理(转)
    iOS 使用cocoaPods总结 ----摩天居士博客
    iOS 开发之本地化 国际化
    iOS 8 Xcode6 设置Launch Image 启动图片<转>
  • 原文地址:https://www.cnblogs.com/ifon/p/11514307.html
Copyright © 2011-2022 走看看