I'm mainly using Vue, and just recently picked up React. Loving it so far, and its quite similar in a lot of ways to Vue, which makes learning it way easier.
Now, let's consider two siblings component. I want to trigger something in component number one, when something happens in component number two. In Vue you can just bind window.bus = new Vue
, and then emit in one of the components bus.$emit('event')
and bind in the mounted()
of the second component bus.$on('event', this.doSth)
.
How can you achieve that in React?
Event Bus is only a Global Function Register, can you use it
class _EventBus {
constructor() {
this.bus = {};
}
$off(id) {
delete this.bus[id];
}
$on(id, callback) {
this.bus[id] = callback;
}
$emit(id, ...params) {
if(this.bus[id])
this.bus[id](...params);
}
}
export const EventBus = new _EventBus();
The export const
prevent multiple instances, making the class static
For those that are still searching, look at this article: https://www.pluralsight.com/guides/how-to-communicate-between-independent-components-in-reactjs
The solution uses:
document.addEventListener
for $on
;
document.dispatchEvent
for $emit
;
document.removeEventListener
for $off
;
In my use case I had a component that contained a Refresh button that would trigger a data refresh in other components.
I did everything as it was presented in the article. In case you're using React with Functional Components, you might want to use the following useEffect:
useEffect(() => {
// The component might unmount when the request is in progress.
// Because of this an error will appear when we'll try to 'setData'.
let isMounted = true
const getData = () => {
reqData(db, path)
.then(result => {
if (isMounted) {
setData(result) // This is a useState
}
})
}
eventBus.on('refreshData', (data) => {
getData()
})
getData()
return () => {
isMounted = false
eventBus.remove('refreshData')
}
// Do not change the end of this useEffect. Keep it as it is. It simulates componentDidMount.
// eslint-disable-next-line
}, [])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With