Skip to content

Type safe, validated at runtime (by Zod) event emitter and listener hooks for React

License

Notifications You must be signed in to change notification settings

drenther/use-custom-event

Repository files navigation

use-custom-event

Bundle Size npm version types visitor badge

A simple utility to create custom event emitter, listener (subscriber) and React hook for listening. Make the event payload strictly typed using zod

Installation

npm install use-custom-event

Usage

Basic Custom Event Emitter

import { z } from 'zod';
import { createEventEmitter } from 'use-custom-event';

const { emit, subscribe, useEventListener } = createEventEmitter(
  'my-event',
  z.object({
    name: z.string(),
  })
);

// subscribing to the event - payload is strictly typed
// can be done from anywhere in the app (not react specific)
const unsubscribe = subscribe((data) => {
  console.log(data.name);
});
// call unsubscribe to stop listening to the event
unsubscribe();

function App() {
  // using the useEventListener hook
  useEventListener(
    // callback to handle the event - payload is strictly typed
    useCallback((data) => {
      console.log(data.name);
    }, [])
  );

  return (
    <button
      onClick={() => {
        // emitting the event (with payload) - payload is strictly typed
        // can be done from anywhere in the app (not react specific)
        emit({
          name: 'drenther',
        });
      }}
    >
      Trigger Event
    </button>
  );
}

Broadcast Channel Event Emitter

Broadcast Channel is a simple API for communication between browsing contexts in the same origin. It is useful for sending messages between different tabs or windows of the same origin.

import { z } from 'zod';
import { createBroadcastChannelEventEmitter } from 'use-custom-event';

const channel = new BroadcastChannel('my-channel');
const { emit, subscribe, useEventListener } =
  createBroadcastChannelEventEmitter(
    channel,
    z.object({
      name: z.string(),
    })
  );

// subscribing to the event - payload is strictly typed
// can be done from anywhere in the app (not react specific)
const unsubscribe = subscribe((data) => {
  console.log(data.name);
});
// call unsubscribe to stop listening to the event
unsubscribe();

function App() {
  // using the useEventListener hook
  useEventListener(
    // callback to handle the event - payload is strictly typed
    useCallback((data) => {
      console.log(data.name);
    }, [])
  );

  return (
    <button
      onClick={() => {
        // emitting the event (with payload) - payload is strictly typed
        // can be done from anywhere in the app (not react specific)
        emit({
          name: 'drenther',
        });
      }}
    >
      Trigger Event
    </button>
  );
}

Use it for whatever you like and drop us a star!