当某些数据发生变化时如何重新创建useQuery查询函数?

问题描述 投票:0回答:1

我遇到一个问题,当某些数据发生变化时,React Query 中的 useQuery 钩子不会更新其查询函数。这是我的代码:

import { request } from "../utils/fetch-utils";
import { useQuery } from "@tanstack/react-query";
import { CustomError } from "../utils/customError";
import { useCallback, useContext } from "react";
import { OfflineContext } from "../context/OfflineContext";
import { DeckTypeForSearch } from "../types/types";

type SuccessResponseType = {
  title: string;
  cards: { title: string; note: string; cardId: string; _id: string }[];
  _id: string;
};

const getCards = async (
  _id: string,
  deck: DeckTypeForSearch | null
): Promise<SuccessResponseType | null> => {
  if (!deck) {
    try {
      const data = await request.get(`/cards/${_id}`);
      return data?.data;
    } catch (error) {
      if (error instanceof CustomError) {
        // Now TypeScript recognizes 'error' as an instance of CustomError
        throw new CustomError(error?.message, error?.statusCode);
      } else {
        throw new CustomError("Something went wrong!", 503);
      }
    }
  } else if (deck) {
    return { title: deck.title, cards: deck.cards, _id: deck.deck_id };
  }

  return null;
};

const useGetCards = (deck_id: string) => {
  const { deck } = useContext(OfflineContext);


  const queryKey = ["cards", deck_id];
  const getDataCallbackFunction = useCallback(() => {
    return getCards(deck_id, deck);
  }, [deck, deck_id]);

  return useQuery({
    queryKey: queryKey,
    queryFn: () => {
      return getDataCallbackFunction();
    },

    refetchOnWindowFocus: false, // Don't refetch on window focus
    refetchOnReconnect: true, // Refetch on network reconnect
    retry: 0, // no retry on network errorMessage
    gcTime: 10800000, // 3 handleShowUserInfomation
  });
};

export default useGetCards;

假设牌组的初始值为{ title: "我的标题", cards: "我的卡片", _id: "我的id" }。例如,当牌组值更改为 null 时,我使用 queryClient.invalidateQueries 使查询无效,

 queryClient.invalidateQueries({
        queryKey: ["cards", mutationData.deck_id],
      });

查询函数 getCards(deck_id, Deck) 似乎仍然使用 Deck 的初始值,即 { title: "My title", cards: "my cards", _id: "my id" } 而不是 null。我尝试使用 useCallback 重新创建该函数,但它仍然使用旧的牌组值。我希望查询函数在更改时接收更新的牌组值,但这并没有发生。有没有办法保证查询函数是用最新的数据重新创建的? 查询键保持不变,但传递给查询函数的数据会有所不同。 所以这个解决方案不起作用Link

版本-“@tanstack/react-query”:“^5.10.0”,

reactjs react-query tanstackreact-query
1个回答
0
投票

查询键保持不变,但传递给查询函数的数据会有所不同。

这不是查询键的设计工作方式。来自文档

只要查询键[...]对于查询的数据是唯一的,就可以使用它!

因此,如果您想采用这种方法,您还需要将

deck
deck
数据传递给查询键。

但是,我会将

deck
依赖项移出
getCards
,以便
useQuery
仅在需要获取数据时运行。
useQuery
不应该关心缓存已经被
OfflineContext
“缓存”的东西。

const useGetCards = (deck_id: string) => {
  const { deck } = useContext(OfflineContext);

  const queryKey = ["cards", deck_id];

  const runQuery = !deck;

  const query = useQuery({
    queryKey: queryKey,
    queryFn: () => getCards(deck_id),

    refetchOnWindowFocus: false, // Don't refetch on window focus
    refetchOnReconnect: true, // Refetch on network reconnect
    retry: 0, // no retry on network errorMessage
    gcTime: 10800000, // 3 handleShowUserInfomation

    // disable query if deck is present
    enabled: runQuery,
  });

  return {
    // either return data from query or context
    data: runQuery ? query.deck : deck,
    // error from query is probably useful for consumers
    error: query.error,
    ...{
      // other properties from query that are useful for consumers
    },
  };
};

我无法告诉你为什么

invalidateQueries
不起作用,因为你没有显示它何时使用。但我希望它能像你描述的那样工作。

© www.soinside.com 2019 - 2024. All rights reserved.