'React 17.0: passing down actions/events through component hierarchy

My component composition is as below and I want to call refresh(); of each component when the Refresh button is pressed in the Top Comp component.

enter image description here

I experimented with custom events. But I had problems (refresh method gets called multiple times) with it. I implemented the events as below:

EventBus.js:

const EventBus = {
  on(event, callback) {
    document.addEventListener(event, (e) => callback(e.detail));
  },
  dispatch(event, data) {
    document.dispatchEvent(new CustomEvent(event, { detail: data }));
  },
  remove(event, callback) {
    document.removeEventListener(event, callback);
  },
};

TopComp.js:

const TopComp = () => {
  const refresh = () => {
    EventBus.dispatch("refresh", "");
  }

  return <button onClick={() => refresh()} >Refresh</button>
}

Level1Comp1.js:

const Level1Comp1 = () => {
  const refreshData = () => {
    // refresh logic
  }

  useEffect(() => {
    EventBus.on("refresh", () => {
      refreshData();
    });

    return () => {
      EventBus.remove("refresh");
    }
  }, [])
}

I would like to know is there any other way of implementing this.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source