Codementor Events

Build Simple React Apps Using EventEmitters

Published May 24, 2017Last updated Nov 19, 2017
Build Simple React Apps Using EventEmitters

I admit the debate for Redux vs. Flux has been settled and there is no point in a system so trivial as EventEmitter. But having worked with React and Redux for more than a year I found two things:

  1. Redux is hard to wrap your head around for a beginner.
  2. With all the complex things that can be accomplished using Redux, sometimes it might be too much.

In my company we have to develop multiple small modular web portals. So we came up with a simple pattern just for the fun of it.

Note: I have not tried this with larger complicated apps. So be warned!

So, how does this work??

Component

For lack of a better example, I have decided to use a Todo application to demonstrate.

Here's the usual way of implementing a ToDo: https://jsfiddle.net/mokanarangan/ups7z2s4/

Then I added my only client:

/**
* Defines the abstract client
*/
import EventEmitter from 'eventemitter3';
import _ from 'lodash';

export default class BaseClient {

  /**
   * Initiate the event emitter
   */
constructor() {
  this.eventEmitter = new EventEmitter();
}

  /**
   * Adds the @listener function to the end of the listeners array
   * for the event named @eventName
   * Will ensure that only one time the listener added for the event
   *
   * @param {string} eventName
   * @param {function} listener
   */
on(eventName, listener) {
   this.eventEmitter.on(eventName, listener); 
}

  /**
   * Will temove the specified @listener from @eventname list
   *
   * @param {string} eventName
   * @param {function} listener
   */
removeEventListener(eventName, listener) {
  this.eventEmitter.removeListener(eventName, listener);
}

/**
 * Will emit the event on the evetn name with the @payload
 * and if its an error set the @error value
 *
 * @param {string} event
 * @param {object} payload
 * @param {boolean} error
 */
emit(event, payload, error = false) {
  this.eventEmitter.emit(event, payload, error);
}


  /**
   * Returns the event emitter
   * Used for testing purpose and avoid using this during development
   */
getEventEmitter() {
  return this.eventEmitter;
}
}

The comments have hopefully already been added. Now we can separate the two components and connect themit only with events.

Add listener at component mount and remove them at unmout:

// Listen for event 
componentWillMount() { 
  client.on('TODO_ADDED', this.addEvent); 
} 
  
//Remove listener 
componentWillUnmount(){ 
  client.removeListener('TODO_ADDED', this.addEvent);
}

Now you don’t need to pass the addEvent function as a prop.
https://jsfiddle.net/mokanarangan/ne0rt40f/

And voila, it’s done. No more messy passing props through nested components. Instead, you now have simple modular components that are easy to maintain.

This way, we can have multiple modular components that don’t need to know about other components. This is not rocket science, and hopefully this tutorial will help you build simple apps without much hassle.

Discover and read more posts from Mokanarangan Thayaparan
get started
post comments4Replies
Salvador Salvador
4 years ago

The problem with this emitter is that in order to work, you have to save the new Emmiter() in a global space so consumer and sender can communicate defeating the purpose of not using Redux for example

Rajesh Vutukuri
6 years ago

I need a sample code of EventEmitters used in two different components.

steven kauyedauty
7 years ago

What are your thoughts of using rxjs with custom event emitters in React? I haven’t played much with it much myself.

Show more replies