父子组件之间传递信息可以通过 传递 props 或者 传递一个回调函数来进行组件间的通信,那兄弟组件该怎么直接传递信息呢,这里便需要用到库 Pubsubs ,这是一个较多人使用的 react 组件通信的库。

下载

yarn add pubsub-js

基础使用方法

引入

  1. import PubSub from 'pubsub-js'
  2. // 如果使用CommonJS
  3. //const PubSub = require('pubsub-js');

基础使用样例

这里都是使用官网的例子,只不过我翻译为了中文

创建一个订阅

  1. // 创建一个函数用于订阅主题
  2. var mySubscriber = function (msg, data) {
  3. console.log( msg, data );
  4. };
  5. // 将该函数添加到特定主题的订阅者列表中:有人发送第一个参数这个消息了,就执行第二个参数传进来的函数
  6. // 我们保留返回的令牌 如这里就是叫做 token ,以便能够取消订阅(类似于 定时器的 id)
  7. // from the topic later on
  8. var token = PubSub.subscribe('MY TOPIC', mySubscriber);
  9. //异步地发布一个主题
  10. PubSub.publish('MY TOPIC', 'hello world!');
  11. // 同步发布主题,在某些环境中效率更高
  12. //但是当一个主题触发另一个新的主题的,就会令人困惑
  13. // 执行相同的链
  14. // 务必谨慎使用这种方法,USE WITH CAUTION, HERE BE DRAGONS!!
  15. PubSub.publishSync('MY TOPIC', 'hello world!');

要注意的是,订阅主题的参数是两个,一个是 消息名称,第二个才是数据,如果你不想用到第一个参数 也要用-占位,如(-,data)

取消一个订阅

  1. //从此主题取消此订阅者
  2. PubSub.unsubscribe(token);

一个小实例

现在有两个组件,一个名为 Search 用于搜索东西,搜到的东西要传入 List 组件中用于展示


  1. 两个组件的 index.jsx 中都要引入库

    1. //接受订阅消息的 List 组件
    2. componentDidMount(){
    3. PubSub.subscribe('StoL',(msg,stateObj)=>{
    4. this.setState(stateObj)
    5. })
    6. }

    这里我与 生命周期钩子 一同使用,因为这个是一个生成组件之后就要被调用的函数,且第二个参数我直接穿了个箭头函数。箭头函数中的第二个参数就是 一个 状态对象,传进来后直接用于更改 List 组件的状态

    1. //发送消息的 Search 组件里的 search 函数
    2. search = ()=>{
    3. const {keyWordElement:{value:keyWord}} = this
    4. PubSub.publish('StoL',{isFirst:true,isLoading:true})//*
    5. axios.get(`gitee.com/api/v5/search/users?q=${keyWord}`).then(
    6. response => {
    7. PubSub.publish('StoL',{isLoading:false,users:response.data.items})//*
    8. },
    9. error => {
    10. PubSub.publish('StoL',{isLoading:false,err:error.message})//*
    11. }
    12. )
    13. }

    点击搜索后、请求消息成功后、或者是 请求失败后 ,都会发送消息,传递数据给 List

    完善 订阅消息的组件

    1. //接受订阅消息的 List 组件
    2. componentDidMount(){
    3. this.token = PubSub.subscribe('StoL',(msg,stateObj)=>{
    4. this.setState(stateObj)
    5. })
    6. }
    7. componentWillUnmount(){
    8. PubSub.unsubscribe(this.token)
    9. }

    我们保留返回的令牌 如这里就是叫做 token ,以便能够取消订阅(类似于 定时器的 id)


其他高阶一丢丢的使用方法欢迎参考官网

总结

  • 好处在于 可以让父组件干干净净,哪里需要消息就放在哪里
  • 其实不止于兄弟组件,可以方便各个组件间的通信