3

GitHub - bit-about/event: 💫 Tiny and powerful hook-based event system for React

 2 years ago
source link: https://github.com/bit-about/event
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

BitAboutEvent 💫 Tiny and powerful hook-based event system for React. 100% Idiomatic React.

Install

npm i @bit-about/event

Features

  • 100% Idiomatic React
  • 100% Typescript with event types deduction
  • Efficient and hook-based
  • ...with static listener and dispatcher
  • No centralized event provider
  • Tiny - only 1.6kB
  • Just works

Usage

one Define your events set and their payloads

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

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

two Wrap the tree with the EventProvider

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

speaking_head Dispatch your events

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

ear Listen on your events

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

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

Static access

The third element of the events() result tuple is object which provides access in static manner (without hook).

const [AppEventProvider, useAppEvent, appEvent] = events(...)

and then

// 🗣️ Dispatch event
appEvent.dispatch('buttonClicked', 'Hello Allice!')

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

point_right Rerendering

Neither listeners nor event dispatching rerender the component.
The component will only be rerendered if its state is explicitly changed (in e.g. React.useState).

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

  useEvent({
    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 actually payload middlewares.

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

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

dispatch('buttonClicked', 'Alice')
dispatch('avatarClicked')

NOTE:
The library is completely type safe so Typescript will inform you when you use wrong payload anywhere

BitAboutEvent yellow_heartBitAboutState

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

Now you've got completely type-safe side-effects, isn't cool?

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

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

Partners

Credits

License

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 🙇🏻!


ukraine Slava Ukraini


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK