Skip to content

πŸ’« Tiny and powerful hook-based event system for React

License

Notifications You must be signed in to change notification settings

oleystack/event

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

BitAboutEvent πŸ’« Tiny and powerful hook-based event system for React. 100% Idiomatic React.

Bundle size

Install

npm i @bit-about/event

Migrations

v1 -> v2

Events dispatch approach has been changed. There are no longer functions executed using their names in string.

βœ–οΈ old one:

const dispatch = useEvent()
dispatch('onBobPress', 'hello') 

βœ… new one:

const { onBobPress } = useEvent()
onBobPress('hello')

Features

  • 100% Idiomatic React
  • 100% Typescript with event types deduction
  • Listen or dispatch events from a hook...
  • ...or utilise static access
  • No centralized event provider
  • Tiny - only 0.6kB
  • Just works β„’

➑️ Check demo

Usage

1️⃣ Define your events by defining their payload middlewares

import { events } from '@bit-about/event'

const [EventProvider, useEvents] = events({
  buttonClicked: (payload: string) => payload,
  userLogged: () => {},
  modalClosed: () => {},
})

2️⃣ Wrap your components in EventProvider

const App = () => (
  <EventProvider>
    ...
  </EventProvider>
)

πŸ—£οΈ Dispatch your events in one place...

const Button = () => {
  const { buttonClicked } = useEvents()
  
  return (
    <button onClick={() => buttonClicked('Hello')}>
      Call event
    </button>
  )
}

πŸ‘‚ ...and listen for them in another

const Component = () => {
  const [message, setMessage] = React.useState('')

  useEvents({
    buttonClicked: (payload: string) => setMessage(payload)
  })
  
  return <p>{message}</p> // "Hello"
}

Static access

The third result element of events() is object providing access in static manner (without hook).

const [AppEventProvider, useAppEvents, { subscribe, dispatcher }] = events(...)

and then

// πŸ—£οΈ Dispatch event
dispatcher.buttonClicked('Hello Allice!')

// πŸ‘‚ Subscribe and listen on new events
const subscriber = subscribe({
  buttonClicked: (payload: string) => console.log(payload)
})
  
// remember to unsubscribe!
subscriber.unsubscribe()

πŸ‘‰ Re-render

Neither listeners nor events dispatch your components render.
A component will only be rerendered if it's state is explicitly changed (in e.g. React.useState).

const Component = () => {
  const [message, setMessage] = React.useState('')

  useEvents({
    aliceClicked: () => console.log('I DO NOT rerender this component!'),
    bobClicked: () => setMessage('I DO rerender this component!')
  })
  
  return <p>{message}</p>
}

Event Middlewares

Events in events() are payload middlewares. They can transform payload into another.

const [EventProvider, useEvents] = events({
  buttonClicked: (payload) => `Hello ${message}!`, // Transforms string payload to another
  avatarClicked: () => `Bob!`,                     // Provides default payload
})

const { buttonClicked, avatarClicked } = useEvents({
  buttonClicked: (payload) => console.log(payload), // prints "Hello Alice!",
  avatarClicked: (payload) => console.log(payload), // prints "Bob!"
})

buttonClicked('Alice')
avatarClicked()

NOTE:
The library is full type-safe, so Typescript will inform you when you use wrong payload anywhere.

BitAboutEvent πŸ’› BitAboutState

Are you tired of sending logic to a related components?
Move your bussiness logic to hook-based state using @bit-about/state + @bit-about/event.

Now you've got completely type-safe side-effects. Isn't that cool?

import { state } from '@bit-about/state'
import { useEvents } from './auth-events' // Hook generated from events()
import User from '../models/user'

const [UserProvider, useUser] = state(
  () => {
    const [user, setUser] = React.useState<User | null>(null)
    
    useEvents({
      userLogged: (user: User) => setUser(user),
      userLoggout: () => setUser(null)
    })
    
    return user
  }
)

Partners

wayfdigital.com

Credits

License

MIT Β© Maciej Olejnik πŸ‡΅πŸ‡±

Support me

Support me!

If you use my library and you like it...
it would be nice if you put the name BitAboutEvent in the work experience section of your resume.
Thanks πŸ™‡πŸ»!


πŸ‡ΊπŸ‡¦ Slava Ukraini