react组件通信方式之~图解父子组件通信和兄弟组件通信pubsub-js

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

  • 点击按钮打开弹框(父传子)
    • 思路如下:
    • 子组件中有一个弹框(组件),父组件通过props,将控制弹框是否弹出的标识传递给子组件
    • 子组件根据这个标识来控制是否打开弹框
  • 关闭弹框后将点击关闭位置呈现到页面上(子传父)
    • 思路如下:
    • 因为要区分是点击取消按钮还是点击确认按钮关闭的弹框(点击小叉号也是相当于点击取消按钮)
    • 所以在子组件中通过调用父组件传来的函数,且传不同参的方式告知父组件点击的是那个关闭弹框的
    • 当然父组件要提前传递过来一个函数一边子组件能够调用
效果图
react组件通信方式之~图解父子组件通信和兄弟组件通信pubsub-js
文章图片

代码图示分析
react组件通信方式之~图解父子组件通信和兄弟组件通信pubsub-js
文章图片

总结
  • 父组件传递子组件数据,子组件在props中即可接受并使用
  • 子组件传递父组件,需要父组件提前传一个函数给子组件,以便子组件在适当的时候,将子组件中的数据通过调用这个函数,再传递给父组件
兄弟组件通信之方式一 父组件中转(不推荐) 思路
  • 因为兄弟组件直接是无法直接通信的,所以就考虑找一个中转站去通信。
  • 因为兄弟组件都有一个共同的父组件,所以中转站就选择父组件,同时数据也要统一存放在父组件中。
  • 所以原本 兄弟A ===》 兄弟B 的数据流程就变成 兄弟A ===》 父组件 ===》 兄弟B ,即加了一层
需求
假设我们有这样的需求
  • 在纸质书本数组件(Toptop)中有一个按钮,点击让电子书本数(Bottombottom)加一
  • 在电子书本数组件(Bottombottom)中也有一个按钮,对应点击让纸质书本数组件加一
效果图
【react组件通信方式之~图解父子组件通信和兄弟组件通信pubsub-js】react组件通信方式之~图解父子组件通信和兄弟组件通信pubsub-js
文章图片

代码图示分析
react组件通信方式之~图解父子组件通信和兄弟组件通信pubsub-js
文章图片

总结
这种通过父组件做中转的方式不太方便,实际开发项目中,很少用这种方法,了解即可
兄弟组件通信之方式二 pubsub.js消息订阅发布(推荐)
值得一提的时候,vue中也可以使用这个插件,因为这个插件是用原生js写的
需求
此案例的需求和上面的父组件中转案例类似,就是在一个组件中点击按钮,更改另一个组件的状态。我们看一下效果图
效果图
react组件通信方式之~图解父子组件通信和兄弟组件通信pubsub-js
文章图片

代码图示分析
第一步肯定是要先下载pubsub
npm install pubsub-js --save
react组件通信方式之~图解父子组件通信和兄弟组件通信pubsub-js
文章图片

npm上的官方介绍: https://www.npmjs.com/package...
别忘了取消订阅
注意上述案例中,实际写法不太完善,因为在组件挂载后componentDidMount钩子中订阅了消息,所以当组件即将卸载的时候componentWillUnmount钩子中,还需要取消这个事件订阅。简化代码如下:
// 组件挂载订阅消息 componentDidMount() { this.token = PubSub.subscribe("wantAddOneFromPaper", (msg, data) => { // ... }) }// 组件卸载取消订阅消息 componentWillUnmount() { PubSub.unsubscribe(this.token) }

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

    推荐阅读