无效查询不起作用 [React-Query]

yoa*_*n84 29 reactjs react-native react-query

每次用户按下“喜欢”按钮刷新所有查询时,我都试图使查询无效,但尽管遵循了文档,但到目前为止还没有成功。

我有一个获取数据的组件:

  const {
    data: resultsEnCours,
    isLoading,
    isError,
  } = useQueryGetEvents("homeencours", { currentEvents: true });
Run Code Online (Sandbox Code Playgroud)

这是一个自定义钩子,如下所示:

const useQueryGetEvents = (nameQuery, params, callback) => {
  const [refetch, setRefetch] = React.useState(null);
  const refetchData = () => setRefetch(Date.now()); // => manual refresh
  const { user } = React.useContext(AuthContext);
  const { location } = React.useContext(SearchContext);

  const { isLoading, isError, data } = useQuery(
    [nameQuery, refetch],
    () => getFromApi(user.token, "getEvents", { id_user: user.infoUser.id, ...params }),
    // home params => "started", "upcoming", "participants"
    {
      select: React.useCallback(({ data }) => filterAndSortByResults(data, location, callback), []),
    }
  );

  return { data, isLoading, isError, refetchData };
};

export default useQueryGetEvents;
Run Code Online (Sandbox Code Playgroud)

我还有另一个组件“ButtonLikeEvent”,它允许用户喜欢或不喜欢某个事件:

import { useMutation, useQueryClient } from "react-query";
import { postFromApi } from "../../api/routes"; 
...other imports


const ButtonLikeEvent = ({ item, color = "#fb3958" }) => {
  const queryClient = useQueryClient();
  const {
    user: {
      token,
      infoUser: { id },
    },
  } = React.useContext(AuthContext);

  const [isFavorite, setIsFavorite] = React.useState(item.isFavorite);
  const likeEventMutation = useMutation((object) => postFromApi(token, "postLikeEvent", object));
  const dislikeEventMutation = useMutation((object) =>
    postFromApi(token, "postDislikeEvent", object)
  );

  const callApi = () => {
    if (!isFavorite) {
      likeEventMutation.mutate(
        { id_events: item.id, id_user: id },
        {
          onSuccess() {
            queryClient.invalidateQueries();
            console.log("liked");
          },
        }
      );
    } else {
      dislikeEventMutation.mutate(
        { id_events: item.id, id_user: id },
        {
          onSuccess() {
            queryClient.invalidateQueries();
            console.log("disliked");
          },
        }
      );
    }
  };

  return (
    <Ionicons
      onPress={() => {
        setIsFavorite((prev) => !prev);
        callApi();
      }}
      name={isFavorite ? "heart" : "heart-outline"}
      size={30}
      color={color} //
    />
  );
};

export default ButtonLikeEvent;
Run Code Online (Sandbox Code Playgroud)

每次用户单击该按钮时,我都会使查询无效(因为许多屏幕显示类似按钮)。

成功时会显示​​ console.log,但查询不会无效。

任何想法 ?

谢谢

Eli*_*ski 44

我不小心用了

const queryClient = new QueryClient();
Run Code Online (Sandbox Code Playgroud)

代替

const queryClient = useQueryClient();
Run Code Online (Sandbox Code Playgroud)

new QueryClient()创建一个新的反应查询客户端(通常传递到包装在您的应用程序上的上下文),这应该只完成一次。

wheresuseQueryClient返回对应用程序周围的react-query客户端上下文提供的值的引用。您应该在组件内部使用它。

  • 我的确切问题。谢谢 (5认同)

Yar*_*aha 42

另外,还有一个之前没有提到的原因:

如果您使用了enabled选项,useQuery则此类查询将被忽略invalidateQueries。来自文档:

https://tanstack.com/query/latest/docs/react/guides/disabling-queries

该查询将忽略通常会导致查询重新提取的查询客户端 invalidateQueries 和 refetchQueries 调用。

  • 这正是我需要的答案。太感谢了! (6认同)
  • 看来这也是我烦恼的原因!如果忽略“invalidateQueries”,如何使该挂钩无效? (6认同)

TkD*_*odo 17

查询失效不起作用的两个最常见问题是:

  • 键不匹配,因此您试图使缓存中不存在的内容无效。检查开发工具在这里会有所帮助。通常,这是数字/字符串的问题(例如,如果 id 来自 url,它是一个字符串,但在您的密钥中,它是一个数字)。您还可以尝试手动单击invalidate开发工具中的按钮,这样您就会看到失效本身是有效的。

  • queryClient重新渲染时不稳定。如果您new QueryClient()在组件的 render 方法内部调用然后重新渲染,就会发生这种情况。确保queryClient稳定。


Sla*_*lav 10

就我而言,我所要做的就是等待返回的承诺,invalidateQueries然后再离开(使用react-router)。

  • 我也是。却不知道这是一个承诺。谢谢! (6认同)

Mas*_*ece 7

就我而言,无效查询不起作用,因为我试图使另一个页面中使用的查询无效(使用此案例的 useQuery 未呈现)。

我有两个选择来解决这个问题:

  • 使用refetchInactive这样的选项:queryClient.invalidateQueries(key, { refetchInactive: true }),它将重新获取数据而不是“陈旧”数据。
  • refetchOnMount: true调用时使用选项useQuery,这将重新获取挂载上的数据,无论它是否过时。


Sho*_*agi 5

萨米尔和埃利亚夫的想法结合起来对我来说很有效:

  1. QueryClient 仅用于初始化 QueryClientProvider。
const queryClient = new QueryClient();
Run Code Online (Sandbox Code Playgroud)
  1. useQueryClient 在其他地方都使用。
const queryClient = useQueryClient();
Run Code Online (Sandbox Code Playgroud)