T
TanStack3y ago
flat-fuchsia

How to handle updates through websocket?

I'm trying to create a chat and made the following mutation hook to be called on incoming websocket messages:
import { useMutation, useQueryClient } from "@tanstack/react-query";

function useAddIncomingMessage() {

const queryClient = useQueryClient();

return useMutation(({ selectedChat, msg }) => {
queryClient.setQueryData(
{ queryKey: ["chatMessages", selectedChat] },
(cache) => {
const cacheCopy = { ...cache };
cacheCopy.pages[0].results = [
msg,
...cacheCopy.pages[0].results,
];
return cacheCopy;
}
);
});
}

export default useAddIncomingMessage;
import { useMutation, useQueryClient } from "@tanstack/react-query";

function useAddIncomingMessage() {

const queryClient = useQueryClient();

return useMutation(({ selectedChat, msg }) => {
queryClient.setQueryData(
{ queryKey: ["chatMessages", selectedChat] },
(cache) => {
const cacheCopy = { ...cache };
cacheCopy.pages[0].results = [
msg,
...cacheCopy.pages[0].results,
];
return cacheCopy;
}
);
});
}

export default useAddIncomingMessage;
In my component I use it like this:
const { mutate } = useAddIncomingMessage();

useEffect(() => {
const callback = (msg) => {
mutate({ selectedChat, msg });
};
webSocketService.on("chat.message", callback);
return () => webSocketService.off("chat.message", callback);
}, [mutate]);
const { mutate } = useAddIncomingMessage();

useEffect(() => {
const callback = (msg) => {
mutate({ selectedChat, msg });
};
webSocketService.on("chat.message", callback);
return () => webSocketService.off("chat.message", callback);
}, [mutate]);
However, initially the queryCache is undefined, until I do a Javascript hot reload. What would be a better approach? I tried moving the useEffect into my hook and use queryclient as a dependency but it does not make a difference.
1 Reply
flat-fuchsia
flat-fuchsiaOP3y ago
Update: I got it working by doing this:
const queryClient = useQueryClient();
const queryClientRef = useRef(null);

useEffect(() => {
queryClientRef.current = queryClient;
}, [queryClient]);

const { mutate } = useMutation(({ chatId, msg }) => {
const queryClient = queryClientRef.current;

queryClient.setQueryData(["chatMessages", chatId], (cache) => {
const cacheCopy = { ...cache };
cacheCopy.pages[0].results = [msg, ...cacheCopy.pages[0].results];
return cacheCopy;
});
});
const queryClient = useQueryClient();
const queryClientRef = useRef(null);

useEffect(() => {
queryClientRef.current = queryClient;
}, [queryClient]);

const { mutate } = useMutation(({ chatId, msg }) => {
const queryClient = queryClientRef.current;

queryClient.setQueryData(["chatMessages", chatId], (cache) => {
const cacheCopy = { ...cache };
cacheCopy.pages[0].results = [msg, ...cacheCopy.pages[0].results];
return cacheCopy;
});
});
Still wondering if there is a better way

Did you find this page helpful?