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