【问题标题】:Properly typing Apollo Mutation render prop for onClick handler为 onClick 处理程序正确输入 Apollo Mutation 渲染道具
【发布时间】:2019-05-11 04:31:21
【问题描述】:

我目前正在尝试用 TypeScript 重写 HowToGraphQL 教程,并创建了一个带有相应查询的自定义突变类,如下所示:

export const postMutation = gql`
    mutation PostMutation($description: String!, $url: String!) {
        post(description: $description, url: $url) {
            id
            createdAt
            url
            description
        }
    }
`;

export interface PostMutationData {
    post: {
        id: string;
        createdAt: string;
        url: string;
        description: string;
    };
}

export interface PostMutationVariables {
    description: string;
    url: string;
}

export class PostMutation extends Mutation<PostMutationData, PostMutationVariables> {}

消耗突变的组件基本上是这样的:

<PostMutation mutation={postMutation} variables={{ description, url }}>
    {(onMutate) => <button onClick={onMutate}>Submit</button>}
</PostMutation>

不幸的是,编译器抱怨说我不能将onMutate 分配给onClick,并出现以下错误消息:

Type 'MutationFn<PostMutationData, PostMutationVariables>' is not assignable to type '(event: MouseEvent<HTMLButtonElement>) => void'.
    Types of parameters 'options' and 'event' are incompatible.
        Type 'MouseEvent<HTMLButtonElement>' has no properties in common with type 'MutationOptions<PostMutationData, PostMutationVariables>'.

我想知道如何正确地将onMutate 处理程序分配给onClick

【问题讨论】:

    标签: reactjs typescript graphql apollo


    【解决方案1】:

    onMutate 函数需要一个名为“options”的对象参数作为其第一个参数。您试图将其分配给 onClick,它的第一个参数是事件类型,这使得类型不兼容。

    有几种方法可以解决此问题。您可以在声明按钮之前创建一个使用 option 参数调用 onMutate 的函数,然后简单地将所述函数传递给 onClick。

    <PostMutation mutation={postMutation}>
        {(onMutate) => {
            const onMutateFunc = () => onMutate({ variables: { description, url } })
            return (
                <button onClick={onMutateFunc}>Submit</button>}
            )
         }
    </PostMutation>
    

    或者您可以创建一个调用 onMutate 的 onClick 函数。

    // Class level function
    onClick = () => onMutate({ variables: { description, url } })
    
    <PostMutation mutation={postMutation}>
        {(onMutate) => {
            const onMutateFunc = onMutate({ variables: { description, url } })
            return (
                <button onClick={this.onClick}>Submit</button>}
            )
        }
    </PostMutation>
    

    你也可以直接做这个

    <PostMutation mutation={postMutation}>
        {(onMutate) => {
            return (
                <button onClick={() => onMutate({ variables: { description, url } })}>Submit</button>}
            )
        }
    </PostMutation>
    

    【讨论】:

    • 有点题外话:由于渲染性能问题,我建议不要使用第三个变体,因为在重新创建匿名函数时会重新渲染组件。尽管如此,我还是会尝试第一个 sn-p。
    • 是的,我也听说过。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-31
    • 2020-12-01
    • 2018-11-24
    • 1970-01-01
    • 2022-01-20
    • 2022-11-18
    • 2020-09-14
    相关资源
    最近更新 更多