将 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 }}
/>
});
更新:添加了一些说明
我正在使用 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 }}
/>
});