I'm making a basic multiplayer game using React with RTK Query and Socket.io. I followed the RTK Query documentation for subscription case where they made a chat app. Basically the only change I make is instead of appending the new data to the end of an array, I'd use a single object instead I'd like to update. But when I try to use an object, it stays {}.
The annoying thing is if I use the array solution it works just fine. (So just using array[0] as the draft)
So basically the only differencies are:
initGame: builder.query<ClientGame[],...
-> initGame: builder.query<ClientGame,...
queryFn: () => ({ data: [] })
-> queryFn: () => ({ data: {} as ClientGame })
draft[0] = newGameState
-> draft = newGameState
Works fine:
export const menuApi = createApi({
reducerPath: 'menuApi',
baseQuery: fetchBaseQuery({
baseUrl: '/'
}),
tagTypes: ['Menu'],
endpoints: (builder) => ({
initGame: builder.query<ClientGame[], void>({
queryFn: () => ({ data: [] }),
async onCacheEntryAdded(
_, // arg
{ updateCachedData, cacheEntryRemoved }
) {
const socket = getSocket();
try {
socket.on(ServerEvents.InitGame, (newGameState: any) => {
updateCachedData((draft) => {
draft[0] = newGameState
})
})
Won't return with actual data:
export const menuApi = createApi({
reducerPath: 'menuApi',
baseQuery: fetchBaseQuery({
baseUrl: '/'
}),
tagTypes: ['Menu'],
endpoints: (builder) => ({
initGame: builder.query<ClientGame, void>({
queryFn: () => ({ data: {} as ClientGame }),
async onCacheEntryAdded(
_, // arg
{ updateCachedData, cacheEntryRemoved }
) {
const socket = getSocket();
try {
socket.on(ServerEvents.InitGame, (newGameState: any) => {
updateCachedData((draft) => {
draft = newGameState
})
})
Meanwhile I found the answer. Sending the recived data directly is the key.
socket.on(ServerEvents.InitGame, (newGameState: ClientGame) => {
updateCachedData(() => {
return newGameState;
})
})
// Or using the spread operator to update partially
updateCachedData((draft) => {
return { result: { ...draft.result, stage: newStage.result } }
});