如何在特殊事件调度(socket IO消息)时使所有Redux RTK查询无效?

wljmcqd8  于 2023-06-30  发布在  其他
关注(0)|答案(1)|浏览(101)

我想同步SPAReact应用程序的所有用户(几个选项卡,几个用户)。我写了一个简单的react钩子,它监听特定的socket IO消息,并根据一个名为useGetAllEmployeesQuery的消息更新状态变量:

import { useEffect, useState } from 'react'

export function useRefetchOnMessage (messageType) {
  const [needRefetch, setNeedRefetch] = useState()

  if (!window.io.socket) {
    return
  }

  function handleMessage (e) {
    setNeedRefetch(Date.now())
  }

  useEffect(() => {
    window.io.socket.on(messageType, handleMessage)

    return () => {
      window.io.socket.off(messageType, handleMessage)
    }
  }, [])

  return needRefetch
}

当这个事件被调度时,我简单地调用RTK refetch()方法。

const employees = useGetAllEmployeesQuery(officeId)

const needRefreshEmployees = useRefetchOnMessage('employees changed')

useEffect(() => {
  if (!needRefreshEmployees) return

  employees.refetch()
}, [needRefreshEmployees])

因此,我们需要在应用程序中的任何地方调用它,假设我们有5个使用employees query的组件,我们需要在所有组件中调用refetch。而且,当运行一次就足够的时候,可以运行许多查询。(失效一次)
是否可以在Redux RTK查询配置中订阅任何类型的此类事件?

cdmah0mi

cdmah0mi1#

您可以通过使其标记无效来触发订阅查询以进行 re-query。
参见无效标签:Redux操作创建器,可用于手动使automated re-fetching的缓存标记无效。
假设getAllEmployees端点正在提供标签,例如"employees",您可以调度一个操作来使该标记无效,并触发useGetAllEmployeesQuery钩子来重新获取数据。

const api = createApi({
  ...
  endpoints: builder => ({
    ...
    getAllEmployees: builder.query({
      query: ......,
      ...
      providesTags: ["employees"],
    }),
    ...
  }),
});
import { useEffect } from 'react';
import { useDispatch } from 'react-redux';
import api from '../path/to/apiSlice';

export function useRefetchOnMessage (messageType = "", tags = []) {
  const dispatch = useDispatch();

  useEffect(() => {
    const handleMessage = () => {
      dispatch(api.util.invalidateTags(tags));
    };

    window.io?.socket?.on(messageType, handleMessage);

    return () => {
      window.io?.socket?.off(messageType, handleMessage);
    }
  }, [messageType, tags]);
}

UI代码只需要调用钩子,将"employees"标记传递给useRefetchOnMessage钩子。

const employees = useGetAllEmployeesQuery(officeId);
useRefetchOnMessage('employees changed', ["employees"]);

相关问题