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

Posted

技术标签:

【中文标题】将 ownProps 传递给 Apollo graphql 包装的组件【英文标题】:Passing ownProps into component wrapped by 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
            />
        );
    
);

【问题讨论】:

【参考方案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。再次感谢您抽出宝贵时间。

以上是关于将 ownProps 传递给 Apollo graphql 包装的组件的主要内容,如果未能解决你的问题,请参考以下文章

将所有 Meteor 用户传递给 Apollo 上下文

是否可以将变量传递给 react-apollo 的“儿童”道具?

将 ID 从 React 传递给 Apollo 以找到正确的结果?

mapStateToProps 和 mapDispatchToProps 中的 ownProps arg 有啥用?

如何正确地将变量传递给 apollo useQuery?

使用 graphql 将道具传递给高阶组件时出现 React-apollo Typescript 错误