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

时间:2017-11-05 20:14:46

标签: typescript graphql-js apollo react-apollo

更新:添加了一些说明

我正在使用Apollo graphql包装器来包装组件。我想将onPaymentLoaded OwnProps属性发送到包装函数中。我尝试这样做的方法如下所示。但是,如果我不将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}
            />
        );
    }
);

1 个答案:

答案 0 :(得分:1)

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

其次,

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

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

另外我建议使用recompose的compose func,因为graphql enhancer可能不是唯一的。

希望这个例子,如果我的帮助:

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 }}
  />


});