美文网首页
带小白学react之组件通信

带小白学react之组件通信

作者: 喜剧之王爱创作 | 来源:发表于2019-05-25 21:02 被阅读0次

    本文章依然是一篇react学习入门文章,适合对react理解混乱的你。
    稍微接触过react的同学都知道react有一下几个特点

    • 虚拟DOM
    • 组件化
    • 单向数据流
    • JSX语法
      对于虚拟DOM和JSX语法,大多数react初级使用者都没有去深究虚拟DOM的原理,只知道这是一种diff算法,对于JSX也仅仅是当HTML那样写页面,至于它的编译原理什么的都也没有去深究,当然,对于以上两个react的特点,即使是不去深究,也不影响开发,稀里糊涂照样可以完成每日的开发任务(这一现象,是我在面试过各种react应聘者后发现的现象),所以这里要插一句,要想得到提高应该了解更多的深层原理,不要把要求停留在当前的开发中。
      当然,本文章是面向react小白开发者的,所以要学习这篇文章,也不会对读者有太高要求,以上两点react特性,不了解也罢。但是react的组件化单向数据流却是您不得不了解学习的东西,它将决定您是否真正的用清晰的头脑在开发。

    react的组件化

    上篇文章中,我们介绍 了React的两种组件类型(类组件和纯函数组件),关于组件的化的优势,这里不做详细的介绍,网上有很多好文可以供您学习组件化的优势,意思大致为,组件化可以实现开发过程中的复用,提高开发效率同时也可以把优秀的组件共享给外界,甚至可以维护专门的组件库来供所有react开者使用,比如众所周知的antd就是一个优秀的react组件库。当然组件化开发最大的优势还是将应用拆分成不同的模块,这样应用就变成了一块一块的加载,结合react的diff算法,我们的应用渲染性能将得到很大的提升。
    我们以antd-pro的一个demo为例

    微信图片_20190525190539.png
    这是一个react应用,在上面图片中,我用红色框框出了部分组件,可以很明显的看到,这个应用是由一个一个的组件拼起来的,在应用加载时,我们只加载改变的组件,这样是不是性能大大提高了呢?其中不难发现有的组件是并列关系,有的组件是包含关系,这就是react组件化中一个很重要的概念叫父子组件

    react中父子组件的通信

    在react中提到stateprops是一点都不陌生的,那么他们分别是来承担什么任务呢?
    state存在于类组件中,用来存放组件自身的属性,而props我们既可以在类组件中看法,又可以在函数组件中看到,那么它是用来干什么的呢?props就像一个信息载体,它将带着信息在组件之间进行传递。那么props的值来自何处呢?下面我将用代码告诉大家。

    import React from 'react'
    
    class ComponentOne extends React.PureComponent {
      componentDidMount(){ }
      render(){
        console.log(this.props.content)
        return (
          <div>
            <p>{this.props.content}</p>
          </div>
        )
      }
    }
    export default ComponentOne 
    

    你会发现,这时页面一片空白,然后你在控制台打印结果是undefined,说明这时你的props中并没有content这个值。那么怎么才能让Component这个组件的props中有content这样的值呢?这就是我们要说的父子组件通信,现在我们再创建一个组件。这里我们创建的是一个函数组件。

    import React from 'react'
    import ComponentOne from './***'//我们在此处引用上面的组件
    
    const ComponentTwo = () => {
      return (
        <div>
          <ComponentOne
            content='这是组件二传给组件一的值'
             haha='这是组件二随便传给组件一的一个haha属性'
           />
        </div>
    )
    }
    export default ComponentTwo 
    

    这时我们在刚才ComponentOne 的路由下加载ComponentTwo ,我们会发现,页面中出现了‘这是组件二传给组件一的值’这样的字样,也就是说,我们ComponentTwo 组件将值传到了ComponentOne,并且我们还会发现,当我们在ComponentOne组件中打印this.props.haha时,打印结果是“这是组件二随便传给组件一的一个haha属性”,这里ComponentTwo 是ComponentOne 的父组件,我们不难发现,父组件是可以向子组件以props的形式传任何值的。这样我们就实现了父组件向子组件传值。那么可能大家会有疑问,子组件能不能像父组件传值呢?答案当然是不能,这就是react的单向数据流,不相信的同学可以自己试一试,这里将不再演示。
    那么既然子组件不能向父组件传值,我们怎么实现父子组件之间的相互通信呢?也就是说,子组件能不能操控父组件呢?答案是能。刚才我说到,父组件可以向子组件以props的形式传递任何信息,那么我们现在传一个函数试试。同样是上面的两个组件。

    //ComponentTwo.js
    import React from 'react'
    import ComponentOne from './ceshiView'//我们在此处引用上面的组件
    
    const ComponentTwo = () => {
      const ceshiFun = (data) => {
         alert(data)
      }
      return (
        <div>
          <ComponentOne
            ceshi = {ceshiFun}
           />
        </div>
    )
    }
    export default ComponentTwo 
    
    //ComponentOne.js
    
    import React from 'react'
    
    class ComponentOne extends React.PureComponent {
      componentDidMount(){ }
      buttonClick = () => {
        this.props.ceshi('组件一向组件二传递的信息')
      }
      render(){
        return (
          <div>
            <button onClick={this.buttonClick}>点我</button>
          </div>
        )
      }
    }
    export default ComponentOne 
    

    如果您按照上面的代码做了实验,您会发现,当点击按钮的时候,我们页面中会弹出“组件一向组件二传递的信息”,这说明我们的子组件ComponentOne将值传到了父组件ComponentTwo 中,实现了子组件像父组件的通信,并且是以作用域为父组件的函数这样的形式传过去的,通俗的说就是,父组件向子组件传一个定义在父组件中的函数,然后子组件通过props拿到它调用。
    这时可能有的读者会有疑问,刚才不是说react是单向数据流,只能是父传子吗?怎么现在子组件也给父组件传值了?不是矛盾了吗?这里并不是矛盾,react的单向数据流指的是传值而非通信,传值即通过props单向传,而通信是子组件调的父组件传过来的一个方法,这里是依然遵循父传子的,并且这样实现了互相通信。
    读到这里,文章以及接近尾声,我想大家一定对react的组件通信有了一定的了解,在react开发过程中头脑将更加清晰,也知道了props的主要来源,那就是父组件给传过来的。这里注意我说的是主要来源,细心的读者可能会发现难道还有次要来源,没错,那就时被某些高阶函数包装后,也是可以给props中传值的。比如使用redux的同学会见到connect这样的高阶函数,比如使用antd组件库的同学会见到creatForm这样的函数,被类似于这样的高阶函数包装,也是可以往props中加入某些属性和方法的,当然这就无关组件通信了,我这里只是简单的提一下,主要还是为了让大家记住props是react信息传递的载体!,后续关于redux的文章,我会详细讲解这样的高阶函数,读完本文章的同学,还是把主要学习尽力放在今天的主题上,那就时组件之间的通信。
    文章至此结束,感谢您的浏览!

    相关文章

      网友评论

          本文标题:带小白学react之组件通信

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