While React Query is very feature rich, it misses one thing - support for streams, event emitters, WebSockets etc. This library leverages React Query's useQuery to provide useSubscription hook for subscribing to real-time data.
React Query useQuery's query function is any function which returns a Promise. Similarly, useSubscription's subscription function is any function which returns an Observable.
npm install react-query-subscription react react-query@3 rxjs@7or
yarn add react-query-subscription react react-query@3 rxjs@7Please see examples.
TODO
import { QueryClientProvider, QueryClient } from 'react-query'; import { ReactQueryDevtools } from 'react-query/devtools'; import { useSubscription } from 'react-query-subscription'; import { eventSource$ } from 'rx-event-source'; const queryClient = new QueryClient(); function App() { return ( <QueryClientProvider client={queryClient}> <SseExample /> <ReactQueryDevtools initialIsOpen={false} /> </QueryClientProvider> ); } function SseExample() { const { data, isLoading, isError, error } = useSubscription( 'some-key', // @see https://kaciakmaciak.github.io/rx-event-source/modules.html#eventSource_ () => eventSource$('/api/v1/sse'), { // options } ); if (isLoading) { return <div>Loading...</div>; } if (isError) { return ( <div role="alert"> {error?.message || 'Unknown error'} </div> ); } return <div>Data: {JSON.stringify(data)}</div>; }See rx-event-source docs.
GraphQL subscription using graphql-ws
import { QueryClientProvider, QueryClient } from 'react-query'; import { ReactQueryDevtools } from 'react-query/devtools'; import { useSubscription } from 'react-query-subscription'; import { Observable } from 'rxjs'; import { createClient } from 'graphql-ws'; import type { Client, SubscribePayload } from 'graphql-ws'; const queryClient = new QueryClient(); function App() { return ( <QueryClientProvider client={queryClient}> <GraphQlWsExample postId="abc123" /> <ReactQueryDevtools initialIsOpen={false} /> </QueryClientProvider> ); } const client = createClient({ url: 'wss://example.com/graphql' }); /** * @see https://github.com/enisdenjo/graphql-ws#observable */ export function fromWsClientSubscription<TData = Record<string, unknown>>( client: Client, payload: SubscribePayload ) { return new Observable<TData | null>((observer) => client.subscribe<TData>(payload, { next: (data) => observer.next(data.data), error: (err) => observer.error(err), complete: () => observer.complete(), }) ); } interface Props { postId: string; } interface Comment { id: string; content: string; } function GraphQlWsExample({ postId }: Props) { const { data, isLoading, isError, error } = useSubscription( 'some-key', () => fromWsClientSubscription<{ comments: Array<Comment> }>({ query: ` subscription Comments($postId: ID!) { comments(postId: $postId) { id content } } `, variables: { postId, }, }), { // options } ); if (isLoading) { return <div>Loading...</div>; } if (isError) { return ( <div role="alert"> {error?.message || 'Unknown error'} </div> ); } return <div>Data: {JSON.stringify(data?.comments)}</div>; }Thanks goes to these wonderful people (emoji key):
Katarina Anton π» π€ π§ | Jacob Cable π» π€ |
This project follows the all-contributors specification. Contributions of any kind welcome!