[英]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.