|
| 1 | +<div align="center"> |
| 2 | +<h1 align="center">Emittor</h1> |
| 3 | +<h3>State Manager for 'ReactJs | NextJs'</h3> |
| 4 | +<h5>◦ Developed with the software and tools below.</h5> |
| 5 | + |
| 6 | +<p align="center"> |
| 7 | +<img src="https://img.shields.io/badge/Next.js-000000.svg?style&logo=Next.js&logoColor=white" alt="Next.js" /> |
| 8 | +<img src="https://img.shields.io/badge/React-61DAFB.svg?style&logo=React&logoColor=black" alt="React" /> |
| 9 | +<img src="https://img.shields.io/badge/TypeScript-3178C6.svg?style&logo=TypeScript&logoColor=white" alt="TypeScript" /> |
| 10 | +</p> |
| 11 | +<img src="https://img.shields.io/github/license/immiProgrammer/emittor?style&color=5D6D7E" alt="GitHub license" /> |
| 12 | +<img src="https://img.shields.io/github/last-commit/immiProgrammer/emittor?style&color=5D6D7E" alt="git-last-commit" /> |
| 13 | +<img src="https://img.shields.io/github/commit-activity/m/immiProgrammer/emittor?style&color=5D6D7E" alt="GitHub commit activity" /> |
| 14 | +<img src="https://img.shields.io/github/languages/top/immiProgrammer/emittor?style&color=5D6D7E" alt="GitHub top language" /> |
| 15 | +</div> |
| 16 | + |
| 17 | +--- |
| 18 | + |
| 19 | +## 📍 Overview |
| 20 | + |
| 21 | +The custom emittor approach for state management in React offers a convenient way to manage and share states across multiple components without the need to wrap them with providers. By utilizing event-driven architecture, this method simplifies the handling of state updates, making it easy to work with event handlers and propagate changes throughout the application. With this approach, components can subscribe to state changes directly, ensuring seamless communication and synchronization between different parts of the UI. Additionally, it eliminates the boilerplate code associated with provider-based state management solutions, providing a more lightweight and flexible alternative for managing application state. |
| 22 | + |
| 23 | +--- |
| 24 | + |
| 25 | +## 🚀 Getting Started |
| 26 | + |
| 27 | +Install the package with npm: |
| 28 | + |
| 29 | +```sh |
| 30 | +npm install emittor |
| 31 | +``` |
| 32 | + |
| 33 | +or yarn: |
| 34 | + |
| 35 | +```sh |
| 36 | +yarn add emittor |
| 37 | +``` |
| 38 | + |
| 39 | +or pnpm: |
| 40 | + |
| 41 | +```sh |
| 42 | +pnpm add emittor |
| 43 | +``` |
| 44 | + |
| 45 | +--- |
| 46 | + |
| 47 | +## 📖 Usage |
| 48 | + |
| 49 | +First Create `Emittor` in separate file `/lib/emittor.ts` |
| 50 | + |
| 51 | +```ts |
| 52 | +import { createEmittor } from 'emittor' |
| 53 | + |
| 54 | +export const countEmittor = createEmittor(0) |
| 55 | +``` |
| 56 | + |
| 57 | +then: |
| 58 | +connect State with `Emittor` in client Components |
| 59 | + |
| 60 | +```tsx |
| 61 | +"use client"; |
| 62 | +import { countEmittor } from "./lib/emittor"; |
| 63 | + |
| 64 | +function Page() { |
| 65 | + // connect State with `Emittor` in client Components and use like useState Hook |
| 66 | + const [count, setCount] = useEmittor(countEmittor) |
| 67 | + ... |
| 68 | +} |
| 69 | +``` |
| 70 | + |
| 71 | +This adjusted code snippet provides a simple and easy-to-understand usage example of the `emittor` package. It demonstrates using the `useEmittor` hook to manage state, similar to how `useState` is used in React. |
| 72 | + |
| 73 | +> **Warning** </br> |
| 74 | +> Always create an emittor in a separate file</br> |
| 75 | +> Because in development mode, the whole file will be rendered again. That can cause unexpected bugs. |
| 76 | +
|
| 77 | +. |
| 78 | + |
| 79 | +> **Note** </br> |
| 80 | +> create emittor anywhere in your project like [`createContext`](https://react.dev/reference/react/createContext) in React. </br> |
| 81 | +> and import `Emittor` where use or link (in components and other places) |
| 82 | +
|
| 83 | +</br> |
| 84 | + |
| 85 | +Also, use a method that can change only the state without re-rendering this component when the state is changed. |
| 86 | + |
| 87 | +```tsx |
| 88 | +"use client"; |
| 89 | + |
| 90 | +import { countEmittor } from "./lib/emittor" |
| 91 | + |
| 92 | +function Page() { |
| 93 | + return ( |
| 94 | + <button onClick={()=>countEmittor.setState(countEmittor.state+1)}>Add</button> |
| 95 | + ) |
| 96 | +} |
| 97 | + |
| 98 | +export default Page |
| 99 | +``` |
| 100 | + |
| 101 | +</br> |
| 102 | + |
| 103 | +## Emittor In Multiple Components |
| 104 | + |
| 105 | +The emittor package enables automatic state synchronization across React components. By simply integrating emittor, any component subscribing to state changes will update whenever the state changes anywhere in the application. This eliminates the need for manual state passing or provider wrapping, streamlining development and enhancing component responsiveness. |
| 106 | + |
| 107 | +```tsx |
| 108 | +import { useEmittor } from "emittor" |
| 109 | +import { countEmittor } from "./lib/emittor" |
| 110 | + |
| 111 | +function Page(){ |
| 112 | + return( |
| 113 | + <> |
| 114 | + <View /> |
| 115 | + <Button/> |
| 116 | + </> |
| 117 | + ) |
| 118 | +} |
| 119 | + |
| 120 | +// This component only re-renders when the state is changed. |
| 121 | +function View(){ |
| 122 | + const [count, setCount] = useEmittor(countEmittor) |
| 123 | + return( |
| 124 | + <div> |
| 125 | + {count} |
| 126 | + </div> |
| 127 | + ) |
| 128 | +} |
| 129 | + |
| 130 | +function Button() { |
| 131 | + return ( |
| 132 | + <button onClick={()=>countEmittor.setState(countEmittor.state+1)}>Add</button> |
| 133 | + ) |
| 134 | +} |
| 135 | + |
| 136 | +export default Page |
| 137 | +``` |
| 138 | + |
| 139 | +</br> |
| 140 | + |
| 141 | +### Other Usage |
| 142 | + |
| 143 | +You can also use the emitter in event listeners or other functions to modify state. |
| 144 | + |
| 145 | +```ts |
| 146 | +countEmittor.getState() |
| 147 | +countEmittor.setState(10) |
| 148 | +// also use use directly |
| 149 | +countEmittor.state |
| 150 | +countEmittor.state = 10 |
| 151 | +``` |
| 152 | + |
| 153 | +It will re-render those components where that emitter is used. |
| 154 | +</br> |
| 155 | + |
| 156 | +## Usage of `ReducerEmittor` |
| 157 | + |
| 158 | +First Create `ReducerEmittor` in separate file `/lib/emittor.ts` |
| 159 | + |
| 160 | +```ts |
| 161 | +import { createReducerEmittor } from "emittor" |
| 162 | + |
| 163 | +export const countREmittor = createReducerEmittor(0, { |
| 164 | + increment: e=> { |
| 165 | + e.setState(e.state+1) |
| 166 | + }, |
| 167 | + decrement: e=> { |
| 168 | + e.setState(e.state-1) |
| 169 | + } |
| 170 | +}) |
| 171 | +``` |
| 172 | + |
| 173 | +then use like this |
| 174 | + |
| 175 | +```tsx |
| 176 | +"use client"; |
| 177 | +import { useEmittor } from "emittor" |
| 178 | +import { countREmittor } from "./lib/emittor"; |
| 179 | + |
| 180 | +export default function Page() { |
| 181 | + const [count, setCount] = useEmittor(countREmittor) |
| 182 | + |
| 183 | + return ( |
| 184 | + <div className="flex gap-8"> |
| 185 | + <button className="bg-slate-700 p-3"> |
| 186 | + {count} |
| 187 | + </button> |
| 188 | + <button className="bg-slate-700 p-3" onClick={()=>countREmittor.reducers.increment()}> |
| 189 | + + |
| 190 | + </button> |
| 191 | + <button className="bg-slate-700 p-3" onClick={()=>countREmittor.reducers.decrement()}> |
| 192 | + - |
| 193 | + </button> |
| 194 | + </div> |
| 195 | + ); |
| 196 | +} |
| 197 | +``` |
| 198 | + |
| 199 | +</br> |
| 200 | + |
| 201 | +--- |
| 202 | + |
| 203 | +</br> |
| 204 | + |
| 205 | +you can also use `Emittor` like `ReducerEmittor` |
| 206 | +</br> |
| 207 | +in `/lib/emittor.ts` |
| 208 | + |
| 209 | +```ts |
| 210 | +import { createEmittor } from "emittor" |
| 211 | + |
| 212 | +const emittor = createEmittor(0) |
| 213 | + |
| 214 | +function increment(by:number){ |
| 215 | + emittor.setState(emittor.state+by) |
| 216 | +} |
| 217 | + |
| 218 | +function decrement(by:number){ |
| 219 | + emittor.setState(emittor.state-by) |
| 220 | +} |
| 221 | + |
| 222 | +export const countEmittor = { |
| 223 | + emittor, |
| 224 | + increment, |
| 225 | + decrement |
| 226 | +} |
| 227 | +``` |
| 228 | + |
| 229 | +use in Component |
| 230 | + |
| 231 | +```tsx |
| 232 | +"use client"; |
| 233 | +import { useEmittor } from "emittor" |
| 234 | +import { countEmittor } from "./lib/emittor"; |
| 235 | + |
| 236 | +export default function Page() { |
| 237 | + const [count, setCount] = useEmittor(countEmittor.emittor) |
| 238 | + |
| 239 | + return ( |
| 240 | + <div className="flex gap-8"> |
| 241 | + <button className="bg-slate-700 p-3" onClick={()=>setCount(count+1)}> |
| 242 | + {count} |
| 243 | + </button> |
| 244 | + <button className="bg-slate-700 p-3" onClick={()=>countEmittor.increment(10)}> |
| 245 | + + |
| 246 | + </button> |
| 247 | + <button className="bg-slate-700 p-3" onClick={()=>countEmittor.decrement(5)}> |
| 248 | + - |
| 249 | + </button> |
| 250 | + </div> |
| 251 | + ); |
| 252 | +} |
| 253 | +``` |
| 254 | + |
| 255 | +--- |
| 256 | + |
| 257 | +## 🤝 Contributing |
| 258 | + |
| 259 | +Contributions are always welcome! Please follow these steps: |
| 260 | + |
| 261 | +1. Fork the project repository. This creates a copy of the project on your account that you can modify without affecting the original project. |
| 262 | +2. Clone the forked repository to your local machine using a Git client like Git or GitHub Desktop. |
| 263 | +3. Create a new branch with a descriptive name (e.g., `new-feature-branch` or `bugfix-issue-123`). |
| 264 | + |
| 265 | + ```sh |
| 266 | + git checkout -b new-feature-branch |
| 267 | + ``` |
| 268 | + |
| 269 | +4. Make changes to the project's codebase. |
| 270 | +5. Commit your changes to your local branch with a clear commit message that explains the changes you've made. |
| 271 | + |
| 272 | + ```sh |
| 273 | + git commit -m 'Implemented new feature.' |
| 274 | + ``` |
| 275 | + |
| 276 | +6. Push your changes to your forked repository on GitHub using the following command |
| 277 | + |
| 278 | + ```sh |
| 279 | + git push origin new-feature-branch |
| 280 | + ``` |
| 281 | + |
| 282 | +7. Create a new pull request to the original project repository. In the pull request, describe the changes you've made and why they're necessary. |
| 283 | + The project maintainers will review your changes and provide feedback or merge them into the main branch. |
| 284 | + |
| 285 | +--- |
| 286 | + |
| 287 | +## 📄 License |
| 288 | + |
| 289 | +This project is licensed under the `ℹ️ MIT` License. |
| 290 | + |
| 291 | +--- |
0 commit comments