问题描述

我们知道,react组件通信方式有很多种,在项目开发中,我们需要根据:项目复杂程度、业务具体功能、以及组件层级关系,去灵活选择合适的通信方式。本文简述下父子组件和兄弟组件通信的常用方式。至于别的react通信方式(Context、mobx、redux什么的),后续会有对应文章再分类记录。

父子组件通信(父传子、子传父)

需求

假设我们有这样的需求

  • 点击按钮打开弹框(父传子)

    • 思路如下:
    • 子组件中有一个弹框(组件),父组件通过props,将控制弹框是否弹出的标识传递给子组件
    • 子组件根据这个标识来控制是否打开弹框
  • 关闭弹框后将点击关闭位置呈现到页面上(子传父)

    • 思路如下:
    • 因为要区分是点击取消按钮还是点击确认按钮关闭的弹框(点击小叉号也是相当于点击取消按钮)
    • 所以在子组件中通过调用父组件传来的函数,且传不同参的方式告知父组件点击的是那个关闭弹框的
    • 当然父组件要提前传递过来一个函数一边子组件能够调用

效果图

代码图示分析

总结

  • 父组件传递子组件数据,子组件在props中即可接受并使用
  • 子组件传递父组件,需要父组件提前传一个函数给子组件,以便子组件在适当的时候,将子组件中的数据通过调用这个函数,再传递给父组件

兄弟组件通信之方式一 父组件中转(不推荐)

思路

  • 因为兄弟组件直接是无法直接通信的,所以就考虑找一个中转站去通信。
  • 因为兄弟组件都有一个共同的父组件,所以中转站就选择父组件,同时数据也要统一存放在父组件中。
  • 所以原本 兄弟A ===》 兄弟B 的数据流程就变成 兄弟A ===》 父组件 ===》 兄弟B ,即加了一层

需求

假设我们有这样的需求

  • 在纸质书本数组件(Toptop)中有一个按钮,点击让电子书本数(Bottombottom)加一
  • 在电子书本数组件(Bottombottom)中也有一个按钮,对应点击让纸质书本数组件加一

效果图

代码图示分析

总结

这种通过父组件做中转的方式不太方便,实际开发项目中,很少用这种方法,了解即可

兄弟组件通信之方式二 pubsub.js消息订阅发布(推荐)

值得一提的时候,vue中也可以使用这个插件,因为这个插件是用原生js写的

需求

此案例的需求和上面的父组件中转案例类似,就是在一个组件中点击按钮,更改另一个组件的状态。我们看一下效果图

效果图

代码图示分析

第一步肯定是要先下载pubsub

npm install pubsub-js --save

npm上的官方介绍:https://www.npmjs.com/package...

别忘了取消订阅

注意上述案例中,实际写法不太完善,因为在组件挂载后componentDidMount钩子中订阅了消息,所以当组件即将卸载的时候componentWillUnmount钩子中,还需要取消这个事件订阅。简化代码如下:

// 组件挂载订阅消息
componentDidMount() {
    this.token = PubSub.subscribe("wantAddOneFromPaper", (msg, data) => {
       // ...
    })
}

// 组件卸载取消订阅消息
componentWillUnmount() {
    PubSub.unsubscribe(this.token)
}

总结

这种发布订阅方式,是目前开发中比较常用的兄弟组件通信方法。当然其实pubsub.js不是说只能适用于兄弟组件通信,其实任意层级、任意关系的组件通信,都可以使用pubsub的发布订阅通信,功能很强大的。


水冗水孚
1.1k 声望588 粉丝

每一个不曾起舞的日子,都是对生命的辜负