【问题标题】:Passing ownProps into component wrapped by Apollo graphql将 ownProps 传递给 Apollo graphql 包装的组件
【发布时间】:2018-04-17 23:31:51
【问题描述】:

更新:添加了一些说明

我正在使用 Apollo graphql 包装器来包装组件。我想将onPaymentLoaded 中的onPaymentLoaded 属性发送到包装函数中。我的尝试如下所示。但是,如果我不将 onPaymentLoaded 也包含在 Result 接口的一部分中,则代码不会通过 TypeScript 编译器。这非常令人困惑。我的理解是Result 指定了从查询返回的内容——即Payment。那么如果我不添加onPaymentLoaded,为什么编译器会抱怨呢?

const PAYMENT_QUERY = gql`
    query payment($id: ID!) {
        payment(id: $id) {
            id
            amount
        }
    }
`;

interface Result {
    payment: Payment;
    // ----- If I don't include onPaymentLoaded in the Result,
    //       I get the error shown below. I don't understand why.
    //       onPaymentLoaded is not part of the query result!!!
    onPaymentLoaded: (payment: Payment) => void;
}

type WrappedProps = Result & QueryProps;

interface OwnProps {
    paymentid: string;
    onPaymentLoaded: (payment: Payment) => void;
}

const withPayment = graphql<
    Result,
    OwnProps,
    WrappedProps
>(PAYMENT_QUERY, {
    options: ({ paymentid }) => ({
        variables: { id: paymentid }
    }),
    props: ({ data, ownProps }) => ({ ...data, ownProps })
});

export const PaymentContainer = withPayment(
    // ----- Error if interface Result above does not include onPaymentLoaded:
    //       Type 'Response & QueryProps<OperationVariables> &
    //       { children?: ReactNode; }' has no property 'onPaymentLoaded'
    //       and no string index signature."
    ({ loading, error, payment, onPaymentLoaded }) => {
        return (
            <PaymentView
                loading={loading}
                error={error}
                payment={payment}
                onPaymentLoaded={onPaymentLoaded}
            />
        );
    }
);

【问题讨论】:

    标签: typescript graphql-js apollo react-apollo


    【解决方案1】:

    关于第一个错误,对象属性的 shrthand 语法不允许符号中的点。此外,您很可能根本不需要转换道具,因为您的 onPaymentLoaded 无论如何都会被传递下去。

    其次,

    graphql&lt; TResult = {}, TProps = {}, TChildProps = ChildProps&lt;TProps &amp; TResult&gt;

    这意味着你只需要像你所做的那样传递 TResult 和 TProps 应该等于你的 InputProps 并省略第三个泛型

    我还建议使用 recompose 的 compose func,因为 graphql 增强器可能不是唯一的。

    希望这个例子对我有帮助:

    import * as React from 'react';
    import { compose } from 'recompose';
    import graphql from 'react-apollo/graphql';
    import { QueryProps } from 'react-apollo';
    
    import { MenuDishQuery } from '@admin/graphql/types.gen';
    import { MenuDish as MenuDishPres } from '@admin/components';
    import { dataLoadingOrError } from '@common/utils';
    
    const DATA_QUERY = require('./data.gql');
    
    type OwnProps = {
      recipeId: string;
    }
    
    type Data = { data: MenuDishQuery.Query & QueryProps }
    
    type WrappedProps = OwnProps & Data;
    
    
    export const MenuDish = compose<WrappedProps, OwnProps>(
    
      graphql<MenuDishQuery.Query, WrappedProps>(DATA_QUERY, {
        options: props => ({
          variables: {
            recipeId: props.recipeId
          }
        })
      }),
    
      dataLoadingOrError()
    
    
    )(props => {
    
      const { data } = props;
      const { recipe } = data;
    
      return <MenuDishPres
        dish={{ recipe }}
      />
    
    
    });
    

    【讨论】:

    • 您好丹尼尔,感谢您的详细回复。自从我发布我的问题以来,我得出了类似的结论 - 所以我将你的答案标记为正确。但是,我确实有一个未回答的问题。请参阅我对问题和代码的更新。如果您能提供您的想法,那就太好了。附言(1) 我还没有开始写作,因为我首先尝试了解graphql HOC 的基本用法。 (2) 你可能是对的,我可能根本不需要转换道具 - 还没有尝试过。
    • 嗨@Naresh,我已经上传了一个要点,我按照我通常的方式重构了你的代码。希望它会有所帮助! gist.github.com/rasdaniil/67e12967a42571519bfbc59a8e870739
    • 这很有帮助,@Daniel。再次感谢您抽出宝贵时间。
    猜你喜欢
    • 2019-04-02
    • 2020-09-22
    • 2022-11-02
    • 2018-01-27
    • 2018-11-06
    • 2018-07-15
    • 2018-08-16
    • 1970-01-01
    • 2023-03-15
    相关资源
    最近更新 更多