-
I have been trying out React Query with graphql. I couldn't figure out a way to get it working with subscriptions as they are technically not promises but Real-time data. Any ideas on how to get the subscriptions running with react query will greatly help... |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 5 replies
-
Looks like there isn't a direct way to use subscriptions with GraphQL. There were discussions about building something like Since most subscriptions are just updates on the data that was already fetched by one of my graphQL queries, Say I have to fetch a list of tasks My initial Query will look something like this: const useTasks = () => {
return useQuery("tasks", fetchTasks)
} Now, any update on the tasks data will fire a subscription that will give me the modified / new task with an ID. So I add my subscription in const onNewTask = (newTask) => {
queryClient.setQueryData("tasks", oldData => {
return [newTask, ...oldData]
})
}
const useTasks = () => {
useEffect(() => {
const unsubscribe = subscribeToTasks(onNewTask)
return () => unsubscribe()
})
return useQuery("tasks", fetchTasks)
} So far it has been working fine. Have identified a scenario where |
Beta Was this translation helpful? Give feedback.
-
Hey! Been trying to find a solution for awhile now and can't really seem to get one that will work. |
Beta Was this translation helpful? Give feedback.
-
I had the exact same problem. I must admit that the topic of subscriptions in GraphQL is highly confusing especially for new comers (like me). For now (till NestJS would not introduce support for graphql-ws in v9, I just wrote pure WebSocket implementation of the client-side subscriptions: import {NewProductsDocument, Product, ProductsQuery} from "../../generated/graphql";
import {useEffect} from "react";
import {useQueryClient} from "react-query";
const url = 'ws://localhost:9000/graphql';
export const useNewProductsSubscription = ({welderId}) => {
const queryClient = useQueryClient();
useEffect(() => {
const ws = new WebSocket(url, 'graphql-ws');
ws.onopen = () => {
ws.send(JSON.stringify({"type": "connection_init", "payload": {}}));
ws.send(JSON.stringify({
"id": "1",
"type": "start",
"payload": {
"variables": {"welderId": welderId},
"extensions": {},
"operationName": "NewProducts",
"query": NewProductsDocument
}
}))
}
ws.onmessage = (event) => {
const msg = JSON.parse(event.data)
if(msg.type == 'data'){
const data = msg.payload.data.productAdded
queryClient.setQueriesData<ProductsQuery>('Products', (oldData : ProductsQuery) => {
return {...oldData, getLastProducts: [...oldData.getLastProducts, data]};
})
}
}
return () => {
// Unsubscribe before exit
ws.send(JSON.stringify({"id":"1","type":"stop"}))
ws.close()
}
}, [])
} It is heavily based on https://tkdodo.eu/blog/using-web-sockets-with-react-query and just add new data which comes from ws to the cache. schema.graphql: scalar DateTime
type Product {
label: String!
time: DateTime!
}
type Query {
getLastProducts(count: Int!, welderId: Int!): [Product!]!
}
type Subscription {
productAdded(welderId: Int!): Product!
}
subscription.graphql (this query is NewProductsDocument in my case) : subscription NewProducts( $welderId: Int! ){
productAdded(welderId: $welderId) {
time
label
}
} |
Beta Was this translation helpful? Give feedback.
Looks like there isn't a direct way to use subscriptions with GraphQL. There were discussions about building something like
useStreamQuery
but it wasn't implemented. So I came up with my own approach to using subscriptions.Since most subscriptions are just updates on the data that was already fetched by one of my graphQL queries, Say I have to fetch a list of tasks
My initial Query will look something like this:
Now, any update on the tasks data will fire a subscription that will give me the modified / new task with an ID. So I add my subscription in
useEffect
& update the API data directly usingqueryClient