event bus in React?

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?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

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

Method 2

In the case of two sibling components, you would hold the state in the parent component and pass that state as a prop to both siblings:

class ParentComponent extends Component {
  state = {
   specialProp: "bar"
  }

  changeProp = () => {
   // this.setState.. 
  }
  render() {
    return (
      <div>
        <FirstSibling specialProp={this.state.specialProp} />
        <SecondSibling changeProp={this.changeProp} specialProp={this.state.specialProp} />
      </div>
    );
  }
}

Method 3

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
  }, [])

Method 4

A parent component can manage the state and methods consumed by child components when passed down through props.

The following example increments a count. SibOne displays the count and a button in SibTwo increments the count.

class App extends Component {
    constructor(props) {
        super(props);
        this.state = {
            count: 0
        };
    }
    incrementCount = () => {
        this.setState({
            count: this.state.count + 1
        });
    }
    render() {
        return (
            <div className="App">
                <SibOne count={this.state.count}/>
                <SibTwo incrementCount={this.incrementCount}/>
            </div>
        );
    }
}

const SibOne = props => <div>Count: {props.count}</div>;

const SibTwo = props => (
    <button onClick={props.incrementCount}>
        Increment Count
    </button>
);

Demo: https://codesandbox.io/s/zqp9wj2n63

More on Components and Props: https://reactjs.org/docs/components-and-props.html

Method 5

rxjs is one more option that you can explore. check if that can help you as they are providing observable and event based programs. It is also doing similar thing like what Eventbus is doing in vuejs.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x