简体   繁体   English

在 onClick 中使用解构的 useMutation function 时,Apollo 反应 typescript 错误

[英]Apollo react typescript error when using destructured useMutation function in onClick

I was trying out the Odyssey Lift-Off IV ( useMutation Hook ) tutorial using typescript and I can't seem to update a Track's views by Id using the onClick event handler.我正在尝试使用 typescript 的 Odyssey Lift-Off IV ( useMutation Hook ) 教程,但我似乎无法使用 onClick 事件处理程序按 Id 更新 Track 的视图。 In the JavaScript version on the Odyssey website, they called the incrementTrackViews like this:在 Odyssey 网站上的 JavaScript 版本中,他们这样调用 incrementTrackViews:

onClick={incrementTrackViews}

I can't do the same because I'm using TypeScript, so it throws the following error:我不能这样做,因为我使用的是 TypeScript,所以它会引发以下错误:

(JSX attribute) onClick?: React.MouseEventHandler<HTMLAnchorElement> | undefined

Type '(options?: MutationFunctionOptions<any, { incrementTrackViewsId: string; }> |
undefined) => Promise<FetchResult<any, Record<string, any>, Record<string, any>>>' is 
not assignable to type 'MouseEventHandler<HTMLAnchorElement>'. Types of parameters
'options' and 'event' are incompatible. Type 'MouseEvent<HTMLAnchorElement, MouseEvent>'
has no properties in common with type 'MutationFunctionOptions<any, { 
incrementTrackViewsId: string; }>'.ts(2322)

index.d.ts(1463, 9): The expected type comes from property 'onClick' which is declared
here on type 'IntrinsicAttributes & { css?: Interpolation<Theme>; } & Pick<LinkProps<unknown>, 
"slot" | "style" | "title" | "key" | "download" | ... 263 more ... | "innerRef"> & 
RefAttributes<...> & { ...; } & { ...; }'

So, I used a callback function to get rid of the error:因此,我使用了回调 function 来消除错误:

onClick={() => incrementTrackViews}

Unfortunately, the Track Views will not update.不幸的是,Track Views 不会更新。 Here's my code:这是我的代码:

import { gql, useMutation } from "@apollo/client";
import styled from "@emotion/styled";
import { Link } from "@reach/router";
import React from "react";
import { Track as TrackInterface } from "../components/track-detail";
import { colors, mq } from "../styles";
import { humanReadableTimeFromSeconds } from "../utils/helpers";

/**
 * Mutation to increment a track's number of views
 * (exported for tests)
 */
export const INCREMENT_TRACK_VIEWS = gql`
  mutation IncrementTrackViewsMutation($incrementTrackViewsId: ID!) {
    incrementTrackViews(id: $incrementTrackViewsId) {
      code
      success
      message
      track {
        id
        numberOfViews
      }
    }
  }
`;

export interface Track {
  id: string;
  title: string;
  author: Author;
  thumbnail: string;
  length: number;
  modulesCount: number;
  description: string;
  numberOfViews: number;
  modules: Module[];
}

interface TrackCardProps {
  track: Track;
}

/**
 * Track Card component renders basic info in a card format
 * for each track populating the tracks grid homepage.
 */
const TrackCard = ({ track }: TrackCardProps) => {
  const { id, title, thumbnail, author, length, modulesCount } = track;

  const [incrementTrackViews] = useMutation(INCREMENT_TRACK_VIEWS, {
    variables: { incrementTrackViewsId: id },
    // to observe what the mutation response returns
    onCompleted: (data) => {
      console.log(data);
    },
  });

  return (
    <CardContainer to={`/track/${id}`} onClick={() => incrementTrackViews}>
      <CardContent>
        <CardImageContainer>
          <CardImage src={thumbnail} alt={title} />
        </CardImageContainer>
        <CardBody>
          <CardTitle>{title || ""}</CardTitle>
          <CardFooter>
            <AuthorImage src={author.photo} />
            <AuthorAndTrack>
              <AuthorName>{author.name}</AuthorName>
              <TrackLength>
                {modulesCount} modules - {humanReadableTimeFromSeconds(length)}
              </TrackLength>
            </AuthorAndTrack>
          </CardFooter>
        </CardBody>
      </CardContent>
    </CardContainer>
  );
};

export default TrackCard;

The onClick={() => incrementTrackViews} return a function instead of actually calling your function onClick={() => incrementTrackViews} 返回 function 而不是实际调用您的 function

try this尝试这个

onClick={() => {
          incrementTrackViews();
}

With onClick={() => incrementTrackViews} , you are returning the function itself, not the result of the function (void or otherwise).使用onClick={() => incrementTrackViews} ,您将返回 function 本身,而不是 function 的结果(无效或其他)。

To execute the function, you need to call it with () like so:要执行 function,您需要使用()调用它,如下所示:

onClick={() => incrementTrackViews()}

If you don't need to pass any data, you can even shorten this more and just call: onClick={incrementTrackViews} , this tells React that onclick, execute this function as is.如果您不需要传递任何数据,您甚至可以进一步缩短它并调用: onClick={incrementTrackViews} ,这会告诉 React onclick,按原样执行此 function。

If TS still isn't happy, you can add brackets and omit a return statement, this will execute the function but not return anything, which might be what TS is looking for in this case.如果 TS 仍然不满意,您可以添加括号并省略return语句,这将执行 function 但不返回任何内容,这可能是 TS 在这种情况下正在寻找的。

onClick={() => {
          incrementTrackViews();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM