Skip to content

Instantly share code, notes, and snippets.

@icavalheiro
Last active August 27, 2021 23:05
Show Gist options
  • Save icavalheiro/d58815b45d1dc707d53ba0ec7c36334c to your computer and use it in GitHub Desktop.
Save icavalheiro/d58815b45d1dc707d53ba0ec7c36334c to your computer and use it in GitHub Desktop.
React Event Hub (useEvent)
import { useEffect } from 'react';
class EventHub
{
private listeners: {};
constructor ()
{
this.listeners = {};
}
public addListener ( type: string, listener: ( payload: any ) => {} )
{
if ( !this.listeners[ type ] )
{
this.listeners[ type ] = [];
}
this.listeners[ type ].push( listener );
}
public removeListener ( type: string, listener: ( payload: any ) => {} )
{
if ( !this.listeners[ type ] )
return;
this.listeners[ type ] = this.listeners[ type ].filter( x => x != listener );
}
public dispatchEvent ( type: string, payload: any )
{
if ( !this.listeners[ type ] )
return;
for ( let i = 0; i < this.listeners[ type ].length; i++ )
{
this.listeners[ type ][ i ]();
}
}
public useEvent ( type: string, listener: ( payload: any ) => {} )
{
useEffect( () =>
{
this.addListener( type, listener );
return () =>
{
this.removeListener( type, listener );
};
} );
}
}
const eventHub = new EventHub();
export default eventHub;
export var useEvent = eventHub.useEvent.bind( eventHub );
export var dispatchEvent = eventHub.dispatchEvent.bind( eventHub );
@icavalheiro
Copy link
Author

icavalheiro commented Aug 27, 2021

Example usage:

CounterDisplay.js

import { useState } from 'react';
import { useEvent } from '../event-hub.ts';

function CounterDisplay () {
  const [ counter, setCounter ] = useState( 0 );

  useEvent( 'counter_increase', () => {
    setCounter( counter + 1 );
  } );

  return (
    <span>
      Counter { counter }
    </span>
  );
}

export default CounterDisplay;

CounterButton.js

import { dispatchEvent } from "../event-hub.ts";

function CounterButton () {
  return (
    <button onClick={ () => dispatchEvent( 'counter_increase', null ) }>
      Click me
    </button>
  );
}

export default CounterButton;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment