admin管理员组文章数量:1122832
I fetch chats initially, using useQuery
, and then any subsequent updates to chats such as new chats are handled by my realtime socket handlers.
ChatList.js
:
const { data, error, isFetching, isLoading } = useQuery({
queryKey: ["chats"],
queryFn: fetchChats,
staleTime: Infinity,
})
In my SocketContext.js
, whenever I receieve a new chat, I add it to the cache. If the query is initially fetching for the first time, the cache is obviously empty at this point. I check whether this existing chat is already in the cache, and if not I add it to the cache.
socket.on("new_chat", (data) => {
const {chatData} = data
queryClient.setQueryData(["chats"], (prevChats = []) => {
const existingChat = prevChats?.find((c) => c._id === chatData._id)
// Add to cache if not already there
if (!existingChat) return [chatData, ...prevChats]
const filteredChats = prevChats.filter((c) => c._id !== existingChat._id)
const updatedChat = { ...existingChat, latestMessage: message }
return [updatedChat, ...filteredChats]
}) })
The problem I have is that if a chat is added to the cache whilst initially fetching, it is then overwritten when useQuery
finishes fetching. This data from useQuery
may not include this new chat. I tried to call invalidateQueries
given I receieve a chat in realtime and isFetching
for the chats
is true, however this is pointless as the cache is empty at this point so invalidateQueries
does nothing.
One solution I tried was storing realtime updates in a queue
whilst isFetching
is true for the chats
query and then merge the updates once fetching completes, however this seems tedious especially considering onSuccess
was removed from the useQuery
hook. Any ways I could potentially handle this?
I fetch chats initially, using useQuery
, and then any subsequent updates to chats such as new chats are handled by my realtime socket handlers.
ChatList.js
:
const { data, error, isFetching, isLoading } = useQuery({
queryKey: ["chats"],
queryFn: fetchChats,
staleTime: Infinity,
})
In my SocketContext.js
, whenever I receieve a new chat, I add it to the cache. If the query is initially fetching for the first time, the cache is obviously empty at this point. I check whether this existing chat is already in the cache, and if not I add it to the cache.
socket.on("new_chat", (data) => {
const {chatData} = data
queryClient.setQueryData(["chats"], (prevChats = []) => {
const existingChat = prevChats?.find((c) => c._id === chatData._id)
// Add to cache if not already there
if (!existingChat) return [chatData, ...prevChats]
const filteredChats = prevChats.filter((c) => c._id !== existingChat._id)
const updatedChat = { ...existingChat, latestMessage: message }
return [updatedChat, ...filteredChats]
}) })
The problem I have is that if a chat is added to the cache whilst initially fetching, it is then overwritten when useQuery
finishes fetching. This data from useQuery
may not include this new chat. I tried to call invalidateQueries
given I receieve a chat in realtime and isFetching
for the chats
is true, however this is pointless as the cache is empty at this point so invalidateQueries
does nothing.
One solution I tried was storing realtime updates in a queue
whilst isFetching
is true for the chats
query and then merge the updates once fetching completes, however this seems tedious especially considering onSuccess
was removed from the useQuery
hook. Any ways I could potentially handle this?
1 Answer
Reset to default 0You need to do Queue Realtime Updates
Store new chats in a queue while fetching:
const newChatsQueue = useRef([]);
socket.on("new_chat", (data) => {
const { chatData } = data;
if (isFetching) {
newChatsQueue.current.push(chatData);
} else {
updateChats(chatData);
}
});
const updateChats = (chatData) => {
queryClient.setQueryData(["chats"], (prevChats = []) => {
const exists = prevChats.some((c) => c._id === chatData._id);
if (!exists) return [chatData, ...prevChats];
return prevChats;
});
};
Apply the queue after fetching completes:
useEffect(() => {
if (!isFetching && newChatsQueue.current.length) {
queryClient.setQueryData(["chats"], (prevChats = []) => [
...newChatsQueue.current,
...prevChats,
]);
newChatsQueue.current = [];
}
}, [isFetching]);
This avoids overwriting realtime updates during the initial fetch.
本文标签: reactjsHandling realtime socket events whilst initially fetching queryStack Overflow
版权声明:本文标题:reactjs - Handling realtime socket events whilst initially fetching query - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736302431a1931530.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论