我正在使用React开发一个在线store .我有一个功能,在点击一个按钮,产品被添加到Collection 夹.在此操作之后,我想更新配置文件请求(返回用户和Collection 夹).

我的代码:

// useProfile.ts

import UserService from "@/services/user.service";
import { useQuery } from "@tanstack/react-query";
import { useUser } from "./useUser";

export const useProfile = () => {
  const { user } = useUser();

  const { data } = useQuery({
    queryKey: ['profile'],
    queryFn: () => {
      return UserService.getProfile(user?.id || "");
    },
    select: ({ data }) => data
  });

  return {profile: data};
};
// LikeButton.tsx

import { useRef } from 'react';
import classes from './LikeButton.module.scss';
// @ts-ignore
import { ReactComponent as IconHeart } from '@/assets/img/svg/icon-heart.svg';
import { useProfile } from '@/hooks/useProfile';
import UserService from '@/services/user.service';
import { useMutation, useQueryClient } from '@tanstack/react-query';

interface ILikeButtonProps {
  productId: number;
}

function LikeButton({ productId }: ILikeButtonProps) {
  const { profile } = useProfile();
  const { invalidateQueries } = useQueryClient();

  const { mutate } = useMutation({
    mutationKey: ['toggle favourite'],
    mutationFn: () => UserService.toggleFavourite(productId),
    onSuccess: () => {
      console.log('onSuccess');
      invalidateQueries({ queryKey: ['profile'] });
    },
  });

  const btnRef = useRef<HTMLButtonElement>(null);

  const buttonClasses = profile?.favourites.some((fp) => fp.id === productId)
    ? `${classes.btn_like} ${classes['btn_like--active']}`
    : classes.btn_like;

  return (
    <button
      ref={btnRef}
      className={buttonClasses}
      onClick={() => mutate()}
      data-product-id={productId}
    >
      <IconHeart />
    </button>
  );
}

export default LikeButton;

然而,由于某些原因,无效查询似乎不起作用,或者我可能做错了什么……我在网上找不到答案:

我添加了console.log--它工作得很好.但并未触发invaliateQueries.

推荐答案

据我所知,在reproduction杆中,你不能从useQueryClient钩上解体.这意味着在执行时,需要将函数(如invaliateQueries)绑定到QueryClient.

这将会奏效:

  // cannot destructure invalidateQueries
  const queryClient = useQueryClient();

  const { mutate } = useMutation({
    mutationKey: ['toggle favourite'],
    mutationFn: () => UserService.toggleFavourite(productId),
    onSuccess: () => {
      console.log('onSuccess');
      queryClient.invalidateQueries({ queryKey: ['profile'] });
    },
  });

析构不起作用:

  // this won't work
  const { invalidateQueries } = useQueryClient();

为了确认,在阅读源代码时,查询客户端确实使用了this-https://github.com/TanStack/query/blob/ca6ad31c19c4d0dcfb8b95c462a575bc79c73bae/packages/query-core/src/queryClient.ts#L54.

如果您解析了invaliateQueries方法,然后调用它,那么它是在没有上下文的情况下被调用的,所以它不知道如何正确使用this-https://github.com/TanStack/query/blob/main/packages/query-core/src/queryClient.ts#L250-L269

Typescript相关问答推荐

如何传递基于TypScript中可变类型的类型?

TypeScript:在作为参数传递给另一个函数的记录中对函数的参数实现类型约束

使用泛型keyof索引类型以在if-condition内类型推断

使用axios在ngOnInit中初始化列表

如何在LucideAngular 添加自定义图标以及如何使用它们

TypeScrip省略了类型参数,仅当传递另一个前面的类型参数时才采用默认类型

Angular文件上传到Spring Boot失败,多部分边界拒绝

在另一个类型的函数中,编译器不会推断模板文字类型

从子类集合实例化类,同时保持对Typescript中静态成员的访问

如何创建内部和外部组件都作为props 传入的包装器组件?

如何在Deno中获取Base64图像的宽/高?

如何从JWT Reaction中提取特定值

如何使用angular15取消选中位于其他组件中的复选框

如何使用useSearchParams保持状态

如何填写Partial的一些属性并让类型系统知道它?

Typescript循环函数引用

使用NextJS中间件重定向,特定页面除外

Typescript泛型验证指定了keyof的所有键

使用 fp-ts 时如何使用 TypeScript 序列化任务执行?

Select 器数组到映射器的Typescript 泛型