evently-react
A Hook-Based Framework for Event-Driven React Apps
📜 Table of Contents
- 🎉 Overview
- ⚡ Features
- 🚀 Getting Started
- 🌟 Use Cases and Kickstarters
- 🔧 Usage
- 🕹️ Advanced Features
- 🔄 Comparison with Redux and Prop Drilling
- 💡 Tips
- 📝 FAQs
- 🛠️ Support and Suggestion
🎉 Overview
evently-react
simplifies event management for React developers. 🚀
Whether you're building a small app or a large-scale application, this package offers a clean and simplified design to manage robust and scalable event-driven architectures.
With its hooks-based API, evently-react
enables seamless event handling while keeping your codebase clean and maintainable.
Say goodbye to prop drilling & global state chaos and hello to elegant, event-driven designs! 🎯
⚡ Features
- 💡 Hooks-based API: Simplifies event management with
useSubscribe
,useEvent
, anduseSubscribeState
. - 🧩 In-memory Caching: Supports late subscribers without missing events.
- 🔗 Middleware Support: Modify or intercept event payloads seamlessly.
- 📂 Typed Events: Built-in TypeScript support ensures type safety.
- ⚙️ Non-React Compatibility: Use exported
EventBus
class for other environments.
🚀 Getting Started
1️⃣ Installation
Install the package using npm or yarn:
npm install evently-react
# OR
yarn add evently-react
2️⃣ Quickstart Example
Below is a quick example to get started with evently-react
.
import React from 'react'
import { EventProvider, useEvent, useSubscribe } from 'evently-react'
// Define a publisher component
const Publisher: React.FC = () => {
const { emitEvent } = useEvent()
const handleClick = () => {
emitEvent('greet', { message: 'Hello from Publisher!' }) // Emit an event
}
return <button onClick={handleClick}>Send Greeting</button>
}
// Define a subscriber component
const Subscriber: React.FC = () => {
useSubscribe('greet', (eventName, payload) => {
console.log(payload.message) // Log the event payload
})
return <p>Listening for greetings...</p>
}
// Wrap your application with EventProvider
const App: React.FC = () => (
<EventProvider>
<Publisher />
<Subscriber />
</EventProvider>
)
export default App
🌟 Use Cases and Kickstarters
evently-react
is designed to simplify communication in complex React applications. Here are some inspiring real-world use cases to help you explore its potential:
1️⃣ Cross-Component Communication
Emit an event in one component and listen to it in another—no need for prop drilling or context juggling.
Example:
- A button in a header component emits an event to toggle a sidebar menu managed by a sibling component.
// In Header component
emitEvent('toggleSidebar', { isVisible: true })
// In Sidebar component
useSubscribe('toggleSidebar', (eventName, payload) => setSidebarVisible(payload.isVisible))
2️⃣ Global Notifications
Create a centralized system for displaying notifications (like toast messages) triggered from anywhere in your app.
Example:
- A failed API call emits an event to show an error toast notification.
emitEvent('showToast', { type: 'error', message: 'Failed to fetch data!' })
3️⃣ Dynamic Data Updates
Trigger UI updates in real-time when backend events or user actions occur.
Example:
- A WebSocket listener emits data updates that a dashboard component subscribes to for live charts or metrics.
// WebSocket listener emits new data
emitEvent('updateMetrics', newMetrics)
// Dashboard listens to updates
useSubscribe('updateMetrics', (eventName, metrics) => updateChart(metrics))
4️⃣ Hybrid State/Event Management
Combine event-driven architecture with existing state management tools (e.g., Redux or Context API) for specific, modular use cases.
Example:
- Use events for decoupled interactions like resetting forms or syncing components without modifying the global state.
// Emit form reset event
emitEvent('resetForm')
// Form component subscribes to reset action
useSubscribe('resetForm', (eventName, payload) => setFormData(initialValues))
By adopting evently-react
, you can create scalable, decoupled, and maintainable solutions for modern web applications. 🎯
🔧 Usage
Emitting Events
Use the useEvent
hook to emit events:
import React from 'react'
import { useEvent } from 'evently-react'
const EmitExample: React.FC = () => {
const { emitEvent } = useEvent()
const handleClick = () => {
emitEvent('exampleEvent', { message: 'Hello, Evently!' }) // Emit an event with a payload
}
return <button onClick={handleClick}>Emit Event</button>
}
export default EmitExample
Subscribing to Events
Use the useSubscribe
hook to listen to events:
import React from 'react'
import { useSubscribe } from 'evently-react'
const SubscribeExample: React.FC = () => {
useSubscribe('exampleEvent', (eventName, payload) => {
console.log('Received payload:', payload) // Logs: { message: 'Hello, Evently!' }
})
return <p>Listening for events...</p>
}
export default SubscribeExample
Subscribing to Multiple Events
Use the enhanced useSubscribe
hook to listen to multiple events:
import React from 'react'
import { useSubscribe } from 'evently-react'
const MultiSubscribeExample: React.FC = () => {
useSubscribe(['eventOne', 'eventTwo'], (eventName, payload) => {
console.log(`Received payload for ${eventName}:`, payload)
})
return <p>Listening for multiple events...</p>
}
export default MultiSubscribeExample
Using State from Events
Leverage the useSubscribeState
hook to access the latest event payload as state:
import React from 'react'
import { useSubscribeState } from 'evently-react'
const StateExample: React.FC = () => {
const latestEventPayload = useSubscribeState('exampleEvent')
return <p>Latest Payload: {latestEventPayload?.message}</p>
}
export default StateExample
🕹️ Advanced Features
Middlewares 🔗
Middleware allows you to intercept or transform events before they are processed.
Global Middleware: .use()
import { useEvent } from 'evently-react'
const App = () => {
const { eventBus } = useEvent()
eventBus.use((event, payload) => {
console.log(`Global Middleware: ${event}`)
return { ...payload, eventSeen: true }
})
return <div>Your App</div>
}
Event-Specific Middleware: .useForEvent()
eventBus.useForEvent('myEvent', (event, payload) => {
console.log(`Event middleware for ${event}`)
return { ...payload, transformed: true }
})
In-Memory Caching 📦
Late subscribers can still receive the latest events:
useSubscribe('exampleEvent', (eventName, payload) => {
console.log('Late subscriber received:', payload) // Works even if the event was emitted earlier
})
Priority-Based Subscription 🚦
Control the execution order of event handlers by assigning priorities. Higher priority callbacks execute first (default is 0
).
// Low priority handler.
useSubscribe('important-event', (eventName, payload) => console.log('Low priority'), 1)
// High priority handler.
useSubscribe('important-event', (eventName, payload) => console.log('High priority'), 3)
Handlers are executed in descending order of priority, making it easy to manage complex event flows.
Accessing EventBus Instance 🚌
The eventBus
instance, accessible via the useEvent
hook, allows integration of evently-react
into non-Component environments such as utility functions or external libraries. This enables advanced use cases like chaining events, transforming payloads, or other customized workflows.
Example: Using EventBus in Utility Functions
The following example demonstrates how to pass the eventBus
instance to a utility function for chaining events:
// Component file
import { useEvent } from 'evently-react'
import { handleEventChain } from './utils'
const Component = () => {
const { eventBus } = useEvent()
// Pass the eventBus instance to utility functions
handleEventChain('logoutUser', eventBus)
return <div>Event Handling Component</div>
}
// utils.ts
import { EventBus } from 'evently-react'
export function handleEventChain(eventName: string, eventBus: EventBus) {
eventBus.subscribe(eventName, payload => {
if (payload.action === 'logout') {
console.log('Logging out user...')
// Emitting new event based on received payload
eventBus.emit('resetPreferences', { message: 'Resetting preferences...' })
}
})
}
Use Cases:
- Chaining Events: Trigger subsequent events based on specific payload conditions.
- Transforming Payloads: Modify or enrich event data before emission using middlewares.
- Non-Component Interactions: Handle events in service layers, utility files, or middleware systems.
Tip: If the use case is completely non-React, consider using the EventBus
class directly. Instead of using hooks, you can create an instance of EventBus
and leverage its methods for event management.
This feature extends the power of evently-react beyond React components, enabling seamless integration in diverse workflows. 🚀
🔄 Comparison with Redux and Prop Drilling
Feature | Redux Equivalent | evently-react Alternative |
---|---|---|
Dispatch actions | dispatch |
emitEvent |
Select state | useSelector |
useSubscribeState |
Middleware/Event Processing | thunks/sagas |
Global & Event-specific Middleware |
Centralized store & reducer boilerplate | Required | Not Required |
Prop drilling | Problematic | Eliminated |
Inject evently-react
seamlessly into existing projects and reduce boilerplate while maintaining scalability.
Note: evently-react
is not intended to replace Redux/Context API or prop drilling entirely. Instead, it provides a complementary event-driven approach to simplify code and improve scalability. By leveraging this pattern, you can reduce boilerplate and decouple components without sacrificing existing architecture.
💡 Tips
- 🎯 Use meaningful event names to keep your event flow intuitive.
- 💾 Middleware can be a powerful way to enforce validation or transformations across events.
- ⚙️ Use in-memory caching to ensure real-time updates for dynamic UIs.
- 🧩 Combine
evently-react
with React context or Redux for hybrid state/event management solutions. - 📦 Explore lazy-loaded modules to reduce initial app load while still utilizing events.
📝 FAQs
1️⃣ What is a real-world use case for evently-react
?
- Cross-Component Communication: Emit an event in one component and listen in another without prop drilling.
- Global Notifications: Show toast notifications across your app.
- Dynamic Data Updates: Trigger real-time UI updates based on backend events.
2️⃣ How do I define types for events in my project?
- Create an
evently.d.ts
file in your project and extend theEvents
type:
import 'evently-react'
declare module 'evently-react' {
export interface Events {
showToast: { message: string; duration: number }
setTheme: { theme: 'light' | 'dark' }
}
}
3️⃣ Can I use evently-react
in non-React environments?
- Yes! You can use the exported
EventBus
class instance to integrate event-based communication in non-React environments. (Example: Vanilla JS, Angular and other frameworks) All methods likeemit
,subscribe
, and middleware support are fully available.
4️⃣ How to subscribe multiple events in one component?
- Simply call
useSubscribe
and give array of event names as parameter. It will listen to all the events provided in the array.
5️⃣ Is there a plan to support other frameworks?
- Yes, there are plans to release individual packages for other frameworks in the future.
🛠️ Support and Suggestion
Having issues or have a suggestion?