3.2 组件之间的通信
在React进行项目开发中,难免会进行组件之间的信息传递操作,即组件间的通信。通信可以简单地理解为组件之间的数据传递,如父子组件之间的通信、同级组件之间的通信等。
在学习组件通信之前,读者应该先对React中的state和props有所掌握。state和props是React中的两种数据方式,无论是state数据还是props数据只要发生数据改变,就会重新渲染组件。那么本节就来讲述state和props的使用方法。
3.2.1 props
props是properties的简称,范围为属性。在React中的组件都是相对独立的,一个组件可以定义接收外界的props,在某种意义上就可以理解为组件定义了一个对外的接口。组件自身相当于一个函数,props可以作为一个参数传入,旨在将任意类型的数据传给组件。
props的使用方法如示例3-1所示。
【示例3-1 props简单使用】
在上面的例子中,先定义一个名为SayName的组件(注意:在React中定义组件一定要用大驼峰法,首字母要大写),在render()中返回一个<h1>的DOM节点,整体渲染<SayName>这个组件的时候,用this.props.name来获取name属性。当然props也可以在挂载组件的时候为其设置初始值,如示例3-2所示。
【示例3-2 初始化props】
props一般不允许更改,所以这里用static关键字来定义默认的props值。在ES5中初始化props使用getDefaultProps()方法来实现,在ES6中统一使用static类型来定义。
提示
props的属性值不允许组件自己修改,如果需要修改props值,请使用state(后面会介绍)
3.2.2 state
state为状态之意。组件在React中可以理解为是一个状态机,组件的状态就是用state来记录的。相对props来说,state是用在组件内部并且是可以修改的。
在state的操作中,基本操作包括初始化、读取和更新。下面通过一个示例来介绍state的基本操作,实现改变DOM元素颜色。
【示例3-3 利用state改变DOM元素颜色】
在上面的例子中,state的初始化放在constructor的构造函数中,该例子中isRed就是一个组件的state,初始化为true。接下来在组件渲染中,即调用rend函数时,<h1>中的this.state.isRed值为true,则style为redStyle,即红色。在<button>中绑定handleClick方法,利用setState来改变state中的isRed值。setState方法有两个参数,官方给出的说明如下:
第一个参数表示的是要改变的state对象,第二个参数是一个回调函数,这个回调函数是在setState的异步操作执行完成并且组件已经渲染后执行的。所以,可以通过该方法获取之前的状态值prevState。该示例就是通过setState获取之前的状态值prevState,对其进行更新操作,从而重新渲染组件。
3.2.3 父子组件通信
在介绍组件通信之前,先引入一个概念:数据流。在React中,数据流是单向的,通过props从父节点传递到子节点,如果父节点的props发生改变,则React会遍历整棵组件树,从而渲染用到这个props的所有组件。
父组件更新子组件,可以直接通过props进行信息传递,实现更新操作,如示例3-4所示。
【示例3-4 子父组件通信】
在父组件<Father />中,dom节点<button>绑定refreshChild()方法,在refreshChild()方法中直接修改state值,传给子组件即可。
子组件更新父组件,需要父组件传一个回调函数给子组件,然后子组件调用,就可以触发父组件更新了,如示例3-5所示。
【示例3-5 父子组件通信】
子组件<Child />调用父组件的refreshParent()方法,触发后修改state值,从而更新父组件内容。
3.2.4 同级组件通信
所谓同级组件,即组件们有一个共同的祖先,但其各自的辈分一样。同级组件之间的通信有两种方式:
·第一种:组件与组件之间有一个共同的父组件,可以通过父组件来通信,即一个子组件可以通过父组件的回调函数来改变props,从而改变另一个子组件的props。
·第二种:组件与组件之间有共同的祖先,但不一定是亲兄弟,这样如果通过父组件一级一级去调用,效率会很差。React提供了一种上下文方式,允许子组件可以直接访问祖先组件的属性和方法,从而使效率得到很大的提升。
兄弟组件通信,如示例3-6所示。
【示例3-6 兄弟组件通信】
<Brother1/>和<Brother2/>是两个兄弟组件,二者有一个共同的父组件,第一个子组件<Brother1/>可以通过父组件<Father/>的回调方法修改state,当父组件的state有了改动之后,其改动的state会传给其所有子组件后重新渲染,这样就达到了兄弟节点之间的通信。