70 |
71 | 💡 light is{' '}
72 | {isLightOn ? (
73 | ON
74 | ) : (
75 | OFF
76 | )}
77 |
78 |
79 | is listening on lightSwitchPressed event
80 | {message}
// "Hello" 93 | } 94 | ``` 95 | 96 | ## Static access 97 | The third result element of `events()` is object providing access in static manner (without hook). 98 | 99 | ```jsx 100 | const [AppEventProvider, useAppEvents, { subscribe, dispatcher }] = events(...) 101 | ``` 102 | 103 | and then 104 | ```jsx 105 | // 🗣️ Dispatch event 106 | dispatcher.buttonClicked('Hello Allice!') 107 | 108 | // 👂 Subscribe and listen on new events 109 | const subscriber = subscribe({ 110 | buttonClicked: (payload: string) => console.log(payload) 111 | }) 112 | 113 | // remember to unsubscribe! 114 | subscriber.unsubscribe() 115 | ``` 116 | 117 | ## 👉 Re-render 118 | Neither listeners nor events dispatch your components render.{message}
131 | } 132 | ``` 133 | 134 | ## Event Middlewares 135 | Events in `events()` are payload middlewares. They can transform payload into another. 136 | 137 | ```jsx 138 | const [EventProvider, useEvents] = events({ 139 | buttonClicked: (payload) => `Hello ${message}!`, // Transforms string payload to another 140 | avatarClicked: () => `Bob!`, // Provides default payload 141 | }) 142 | 143 | const { buttonClicked, avatarClicked } = useEvents({ 144 | buttonClicked: (payload) => console.log(payload), // prints "Hello Alice!", 145 | avatarClicked: (payload) => console.log(payload), // prints "Bob!" 146 | }) 147 | 148 | buttonClicked('Alice') 149 | avatarClicked() 150 | ``` 151 | 152 | > NOTE:
182 |
183 | ## Credits
184 | - [Constate](https://github.com/diegohaz/constate) - approach main inspiration
185 | - [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
186 |
187 | ## License
188 | MIT © [Maciej Olejnik 🇵🇱](https://github.com/macoley)
189 |
190 | ## Support me
191 |
192 | 🇺🇦 Slava Ukraini
200 | -------------------------------------------------------------------------------- /src/__tests__/events.test.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import { fireEvent, render } from '@testing-library/react' 3 | import events from '../events' 4 | import { act } from 'react-dom/test-utils' 5 | 6 | // Counter Component 7 | const Counter = ({ role }: { role: string }) => { 8 | const renderCounter = React.useRef(0) 9 | renderCounter.current = renderCounter.current + 1 10 | return{renderCounter.current}
11 | } 12 | 13 | test('Basic usage', () => { 14 | const aliceListener = jest.fn() 15 | const [Provider, useEvents] = events({ 16 | onAlicePress: (alice: string, bob: number) => `alice:${alice},bob:${bob}`, 17 | onBobPress: () => {} 18 | }) 19 | 20 | const Buttons = () => { 21 | const { onAlicePress, onBobPress } = useEvents() 22 | 23 | return ( 24 | <> 25 |