npm i @bit-about/event
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')
- 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
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"
}
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()
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>
}
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
}
)
- Constate - approach main inspiration
- use-context-selector & FluentUI - fancy rerender avoiding tricks and code main inspiration
MIT © Maciej Olejnik 🇵🇱
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