RTK Query + WebSocket
29 мая 2024 г.
Для обновления данных через webSocket в RTK Query есть функция onCacheEntryAdded.
В примере ниже isMessage - функция проверки, поступили ли данные через webSocket; updateCachedData - обновление кеша RTK Query по этому запросу, draft - экземпляр ваших данных в кеше. Если данные представлены в виде массива, обновляете их через push, как в примере документации RTK Query.
JavaScript
1updateCachedData((draft) => {2 draft.push(data)3})
Если в качестве объекта, то и обновляете как объект.
JavaScript
1updateCachedData((draft) => {2 draft.price = data.price;3 draft.count = data.count;4});
Пример полного кода файла api RTK Query:
typescript | api.ts
1// mock data example2// {3// price: 123,4// count 245// }67import type { Action, PayloadAction } from "@reduxjs/toolkit";8import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";9import { HYDRATE } from "next-redux-wrapper";10import { TPriceResponse } from "@/types";11import { isMessage } from "./schemaValidators";1213type RootState = any;1415function isHydrateAction(action: Action): action is PayloadAction<RootState> {16 return action.type === HYDRATE;17}1819export const baseUrl = process.env.NEXT_PUBLIC_BASE_URL;20export const baseWebsocketUrl =21 process.env.NEXT_PUBLIC_BASE_WEBSOCKET_URL;2223export const mainApi = createApi({24 baseQuery: fetchBaseQuery({ baseUrl: baseUrl }),25 extractRehydrationInfo(action, { reducerPath }): any {26 if (isHydrateAction(action)) {27 return action.payload[reducerPath];28 }29 },30 tagTypes: [`Prices`],31 endpoints: (builder) => ({32 getPrice: builder.query<TPriceResponse, undefined>({33 query: () => `/price`,34 async onCacheEntryAdded(35 arg,36 { updateCachedData, cacheDataLoaded, cacheEntryRemoved }37 ) {38 const ws = new WebSocket(baseWebsocketUrl);39 try {40 await cacheDataLoaded;41 const listener = (event: MessageEvent) => {42 const data = JSON.parse(event.data);43 if (!isMessage(data)) return;44 updateCachedData((draft) => {45 draft.price = data.price;46 draft.count = data.count;47 });48 };495051 ws.addEventListener("message", listener);52 } catch {}53 await cacheEntryRemoved;54 ws.close();55 },56 providesTags: [`Prices`],57 }),58 }),59});6061export const {62 useGetPriceQuery,63 util: { getRunningQueriesThunk },64} = mainApi;
Пример функции isMessage:
JavaScript | schemaValidators.ts
1import { TPriceResponse } from "@/types";23export function isMessage(message: TPriceResponse) {4 if (message?.price || message?.count) {5 return true;6 }789 return false;10}
Документация RTK Query по работе с webSocket.