Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/oleystack/event

πŸ’« Tiny and powerful hook-based event system for React
https://github.com/oleystack/event

event events hook hooks react react-hooks react-native typescript typescript-library

Last synced: 23 days ago
JSON representation

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

Awesome Lists containing this project

README

        


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




Bundle size

## Install

```bash
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:
> ```jsx
> const dispatch = useEvent()
> dispatch('onBobPress', 'hello')
> ```
> βœ… new one:
> ```jsx
> 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](https://bit-about.github.io/event/)

## Usage

1️⃣ Define *your events* by defining their payload middlewares
```jsx
import { events } from '@bit-about/event'

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

2️⃣ Wrap your components in EventProvider
```jsx
const App = () => (

...

)
```

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

```jsx
const Button = () => {
const { buttonClicked } = useEvents()

return (
buttonClicked('Hello')}>
Call event

)
}
```

πŸ‘‚ ...and listen for them in another
```jsx
const Component = () => {
const [message, setMessage] = React.useState('')

useEvents({
buttonClicked: (payload: string) => setMessage(payload)
})

return

{message}

// "Hello"
}
```

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

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

and then
```jsx
// πŸ—£οΈ 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`).

```jsx
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

{message}


}
```

## Event Middlewares
Events in `events()` are payload middlewares. They can transform payload into another.

```jsx
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](https://github.com/bit-about/state)
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?

```tsx
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(null)

useEvents({
userLogged: (user: User) => setUser(user),
userLoggout: () => setUser(null)
})

return user
}
)
```

## Partners
wayfdigital.com

## Credits
- [Constate](https://github.com/diegohaz/constate) - approach main inspiration
- [use-context-selector](https://github.com/dai-shi/use-context-selector) & [FluentUI](https://github.com/microsoft/fluentui) - fancy rerender avoiding tricks and code main inspiration

## License
MIT Β© [Maciej Olejnik πŸ‡΅πŸ‡±](https://github.com/macoley)

## 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