我遇到一个问题,当某些数据发生变化时,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”,
查询键保持不变,但传递给查询函数的数据会有所不同。
这不是查询键的设计工作方式。来自文档:
只要查询键[...]对于查询的数据是唯一的,就可以使用它!
因此,如果您想采用这种方法,您还需要将
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
不起作用,因为你没有显示它何时使用。但我希望它能像你描述的那样工作。