将 ownProps 传递给 Apollo graphql 包装的组件

Passing ownProps into component wrapped by Apollo graphql

更新:添加了一些说明

我正在使用 Apollo graphql 包装器来包装组件。我想将 OwnProps 中的 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}
            />
        );
    }
);

关于第一个错误,对象属性的简写语法不允许在符号中使用点。另外,很可能你根本不需要转换 props,因为你的 onPaymentLoaded 无论如何都会被传递下去。

其次,

graphql< TResult = {}, TProps = {}, TChildProps = ChildProps<TProps & TResult>

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

我还建议使用 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 }}
  />


});