父子组件之间传递信息可以通过 传递 props 或者 传递一个回调函数来进行组件间的通信,那兄弟组件该怎么直接传递信息呢,这里便需要用到库 Pubsubs ,这是一个较多人使用的 react 组件通信的库。
下载
基础使用方法
引入
import PubSub from 'pubsub-js'
// 如果使用CommonJS
//const PubSub = require('pubsub-js');
基础使用样例
创建一个订阅
// 创建一个函数用于订阅主题
var mySubscriber = function (msg, data) {
console.log( msg, data );
};
// 将该函数添加到特定主题的订阅者列表中:有人发送第一个参数这个消息了,就执行第二个参数传进来的函数
// 我们保留返回的令牌 如这里就是叫做 token ,以便能够取消订阅(类似于 定时器的 id)
// from the topic later on
var token = PubSub.subscribe('MY TOPIC', mySubscriber);
//异步地发布一个主题
PubSub.publish('MY TOPIC', 'hello world!');
// 同步发布主题,在某些环境中效率更高
//但是当一个主题触发另一个新的主题的,就会令人困惑
// 执行相同的链
// 务必谨慎使用这种方法,USE WITH CAUTION, HERE BE DRAGONS!!
PubSub.publishSync('MY TOPIC', 'hello world!');
要注意的是,订阅主题的参数是两个,一个是 消息名称,第二个才是数据,如果你不想用到第一个参数 也要用-占位,如(-,data)
取消一个订阅
//从此主题取消此订阅者
PubSub.unsubscribe(token);
一个小实例
现在有两个组件,一个名为 Search 用于搜索东西,搜到的东西要传入 List 组件中用于展示
- 两个组件的 index.jsx 中都要引入库
//接受订阅消息的 List 组件
componentDidMount(){
PubSub.subscribe('StoL',(msg,stateObj)=>{
this.setState(stateObj)
})
}
这里我与 生命周期钩子 一同使用,因为这个是一个生成组件之后就要被调用的函数,且第二个参数我直接穿了个箭头函数。箭头函数中的第二个参数就是 一个 状态对象,传进来后直接用于更改 List 组件的状态
//发送消息的 Search 组件里的 search 函数
search = ()=>{
const {keyWordElement:{value:keyWord}} = this
PubSub.publish('StoL',{isFirst:true,isLoading:true})//*
axios.get(`gitee.com/api/v5/search/users?q=${keyWord}`).then(
response => {
PubSub.publish('StoL',{isLoading:false,users:response.data.items})//*
},
error => {
PubSub.publish('StoL',{isLoading:false,err:error.message})//*
}
)
}
点击搜索后、请求消息成功后、或者是 请求失败后 ,都会发送消息,传递数据给 List
完善 订阅消息的组件
//接受订阅消息的 List 组件
componentDidMount(){
this.token = PubSub.subscribe('StoL',(msg,stateObj)=>{
this.setState(stateObj)
})
}
componentWillUnmount(){
PubSub.unsubscribe(this.token)
}
我们保留返回的令牌 如这里就是叫做 token ,以便能够取消订阅(类似于 定时器的 id)
其他高阶一丢丢的使用方法欢迎参考官网
总结
- 好处在于 可以让父组件干干净净,哪里需要消息就放在哪里
- 其实不止于兄弟组件,可以方便各个组件间的通信