It is a simple set of hooks that can help you implement interaction with your SSE (Server Sent Events) server.
This library works perfectly with both React and React Native.
By the way, there is cool library for React Native that implements EventSource standard 😏.
Wrap your app with EventSourceProvider
component in any place that you want to work with SSE.
const App: React.FC = () => {
return (
<EventSourceProvider>
<Chat />
</EventSourceProvider>
)
}
What cool about this provider is that you can provide your own EventSource implementation. You can use any kind of polyfills for Web or React Native that implements base EventSource standard.
Just pass eventSource
prop to provider like that (by default it uses built in your environment EventSource implementation):
<EventSourceProvider eventSource={EventSource}>
...
</EventSourceProvider>
Now you can create connection to your server within this provider.
Create new connection with useEventSource
hook.
const Chat = () => {
const [messages, setMessages] = useState<ChatMessage[]>([]);
const chatSource = useEventSource({
source: 'https://www.example.com/stream?token=blah',
});
...
}
It returns new (or already existing in EventSourceProvider) instance of EventSource.
You can pass additional connection options in options
field:
const Chat = () => {
const [messages, setMessages] = useState<ChatMessage[]>([]);
const chatSource = useEventSource({
source: 'https://www.example.com/stream?token=blah',
options: {
withCredentials: true,
},
});
...
}
Create event listeners with useEventSourceListener
.
const Chat = () => {
const [messages, setMessages] = useState<ChatMessage[]>([]);
const chatSource = useEventSource({
source: 'https://www.example.com/stream?token=blah',
});
const { startListening, stopListening } = useEventSourceListener<ChatMessage>(
{
source: chatSource,
startOnInit: true,
event: {
name: ChatEvent.NewMessage,
listener: ({ data }) => setMessages([...messages, data]),
},
},
[chatSource],
);
...
}
Second argument is dependency array. It works like useEffect
hook - if it changes, listener will automatically recreate itself with current LexicalEnvironment.
That's it!
Don't forget to add "DOM" lib to your tsconfig.json to get EventSource typings!
Prop | Type | Definition |
---|---|---|
eventSource | typeof EventSource | EventSourceProvider will use this custom EventSource implementation for new connections |
useEventSource<CustomEventSourceOptions, CustomEventSource>({
source: string,
options: {
withCredentials: boolean,
},
});
const {
startListening: () => void,
stopListening: () => void,
} = useEventSourceListener<T>(
listenerOptions: {
source: EventSource,
startOnInit: boolean,
event: {
name: string,
listener: (event: { data: T | undefined, event: Event }) => void,
options?: boolean | AddEventListenerOptions | EventListenerOptions,
},
},
dependencies: any[],
);
stopListening
method stops listening until you manually start it again using startListening
even one element of the dependency array changes.