JSFiddle - React, Tailwind, and code Playground

JavaScript

var EventDispatcher = {
    listeners: {},
    on: function (evt_name, callback) {
        if (!Object.prototype.hasOwnProperty.call(this.listeners,evt_name)) {
            this.listeners[evt_name] = [];
        }
        this.listeners[evt_name].push(callback);
    },
    once: function (evt_name, callback) {
        var once = function () {
            try {
                return callback.apply(this,arguments);
            }
            finally {
                this.off(evt_name, once);
            }
        };
        this.on(evt_name, once);
    },
    off: function (evt_name, callback) {
        if (Object.prototype.hasOwnProperty.call(this.listeners,evt_name)) {
            var listeners = this.listeners[evt_name];
            for (var i = 0, l = listeners.length; i < l; i++) {
                if (listeners[i] === callback) {
                    listeners.splice(i,1);
                    return;
                }
            }
        }
    }, 
    trigger: function (evt_name) {
        if (Object.prototype.hasOwnProperty.call(this.listeners,evt_name)) {
            var listeners = this.listeners[evt_name];
            var args = Array.prototype.slice.call(arguments,1);
            for (var i = 0, l = listeners.length; i < l; i++) {
                listeners[i].apply(this, args);
            }
        }
    }
};

// example usage:
function handler() { console.log.apply(console,arguments); }
EventDispatcher.on('an_event', handler);
EventDispatcher.trigger('an_event','foo','bar',123);
EventDispatcher.off('an_event', handler);
EventDispatcher.trigger('an_event','egg','bacon',456);