Skip to content

Instantly share code, notes, and snippets.

@Dissolutio
Created November 5, 2024 17:20
Show Gist options
  • Save Dissolutio/f1de21e4fe480df4c85e8635db38aee4 to your computer and use it in GitHub Desktop.
Save Dissolutio/f1de21e4fe480df4c85e8635db38aee4 to your computer and use it in GitHub Desktop.
PubSub with event context in React: Fire functions in one element tree from another element tree (handy with React3Fiber)
# Pub/Sub in React Context
While React Context is a great way to share data between components, it doesn't inherently implement the Pub/Sub pattern. However, you can combine the two to create a Pub/Sub system within your React application.
Here's a simple implementation:
```js
import React, { createContext, useContext, useState, useEffect } from 'react';
const EventContext = createContext();
export const EventProvider = ({ children }) => {
const [events, setEvents] = useState({});
const subscribe = (eventName, callback) => {
setEvents((prevEvents) => ({
...prevEvents,
[eventName]: [...(prevEvents[eventName] || []), callback]
}));
};
const unsubscribe = (eventName, callback) => {
setEvents((prevEvents) => ({
...prevEvents,
[eventName]: (prevEvents[eventName] || []).filter(cb => cb !== callback)
}));
};
const publish = (eventName, data) => {
(events[eventName] || []).forEach(callback => callback(data));
};
return (
<EventContext.Provider value={{ subscribe, unsubscribe, publish }}>
{children}
</EventContext.Provider>
);
};
export const useEvent = () => useContext(EventContext);
```
How to use:
Wrap your application with the EventProvider.
```js
import { EventProvider } from './EventContext';
function App() {
return (
<EventProvider>
{/* Your components */}
</EventProvider>
);
}
```
Subscribe to events in components.
```js
import { useEvent } from './EventContext';
function MyComponent() {
const { subscribe, unsubscribe } = useEvent();
useEffect(() => {
const handleEvent = (data) => {
console.log('Event received:', data);
};
subscribe('myEvent', handleEvent);
return () => unsubscribe('myEvent', handleEvent);
}, []);
return (
// ...
);
}
```
Publish events from anywhere in your app:
```js
import { useEvent } from './EventContext';
function AnotherComponent() {
const { publish } = useEvent();
const handleClick = () => {
publish('myEvent', 'Hello from AnotherComponent!');
};
return (
<button onClick={handleClick}>Trigger Event</button>
);
}
```
This approach leverages React Context for providing the Pub/Sub functionality throughout your application, allowing components to communicate in a decoupled manner.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment