T
TanStack3y ago
magic-beige

Websockets & queryClient.setQueryData

Hello everyone, new dev, new to React Query. I am currently using React Query to fetch some initial data from an API, and then, with the help of TkDodo's blog post (https://tkdodo.eu/blog/using-web-sockets-with-react-query) I attempted to update the said data using setQueryData with no success. Before I show you the code, I have a large object that the DOM maps through it twice and renders it to the user. Then the websockets come in and send data to be updated to an individual key in the said object, so I have (& know is not efficient) a function that handles said data and creates a new updated entity object (to be replaced/updated with setQueryData. Is it an ideal way for me to handle this use-case? wouldn't it cause a re-render of all of the components? I want the component data to update individually if possibly, as the data from the websockets is sent to the user. This is the code (mostly taken from TkDodo's blog, thanks :D):
import { useEffect } from 'react';
import { useQueryClient } from '@tanstack/react-query';
import { parseEvent, replaceFieldById, findFieldContainer } from '~/utils/event-handling';

const useReactQuerySubscription = () => {
const queryClient = useQueryClient();

useEffect(() => {
const websocket = new WebSocket('ws://192.168.192.3:22080/webevent');
websocket.onopen = () => {
// console.log('connected');
websocket.send('SUBSCRIBE home WebEvent/1.0');
};
import { useEffect } from 'react';
import { useQueryClient } from '@tanstack/react-query';
import { parseEvent, replaceFieldById, findFieldContainer } from '~/utils/event-handling';

const useReactQuerySubscription = () => {
const queryClient = useQueryClient();

useEffect(() => {
const websocket = new WebSocket('ws://192.168.192.3:22080/webevent');
websocket.onopen = () => {
// console.log('connected');
websocket.send('SUBSCRIBE home WebEvent/1.0');
};
1 Reply
magic-beige
magic-beigeOP3y ago
websocket.onmessage = (event) => {
const { data } = event;
const parsedEvent = parseEvent(data);

// queryClient.invalidateQueries(['status']);
queryClient.setQueriesData(['status'], (oldData: any) => {
const update = (entity: any) => {
const updatedField = findFieldContainer(entity, Object.keys(parsedEvent.data)[0]);

if (!updatedField?.location) return entity;

const updatedEntity =
replaceFieldById(
entity,
updatedField.location.sectionId,
updatedField.updatedField.id,
parsedEvent.data[updatedField.updatedField.id]
) ?? entity;

return updatedEntity;
};
// console.log('oldData', oldData);
return update(oldData);
});
};

return () => {
websocket.close();
};
}, [queryClient]);
};

export default useReactQuerySubscription;
websocket.onmessage = (event) => {
const { data } = event;
const parsedEvent = parseEvent(data);

// queryClient.invalidateQueries(['status']);
queryClient.setQueriesData(['status'], (oldData: any) => {
const update = (entity: any) => {
const updatedField = findFieldContainer(entity, Object.keys(parsedEvent.data)[0]);

if (!updatedField?.location) return entity;

const updatedEntity =
replaceFieldById(
entity,
updatedField.location.sectionId,
updatedField.updatedField.id,
parsedEvent.data[updatedField.updatedField.id]
) ?? entity;

return updatedEntity;
};
// console.log('oldData', oldData);
return update(oldData);
});
};

return () => {
websocket.close();
};
}, [queryClient]);
};

export default useReactQuerySubscription;

Did you find this page helpful?