如何使用 react-adopt 动态设置变异变量?
How to dynamically set variables in mutation with react-adopt?
在我的组件中,我使用 react-adopt 来组合 graphql 查询和突变,这样我的渲染道具就不会变得太乱。我有以下代码:
这是我的突变,它需要一个参数 - planID。
const CREATE_ORDER_MUTATION = gql`
mutation CREATE_ORDER_MUTATION($planID: String!) {
createOrder(planID: $planID) {
planID
name
description
subscriptionType
images
subscriptionType
pricePerMonth
}
}
这是 adopt 函数,它需要进行一些更改,其中之一是 createOrder。 Apollo 的工作方式是我需要在这里将变量 prop 传递给 createOrder 组件。问题是,我此时没有 planID。 planID 仅在实际组件内部可用。
const Composed = adopt({
toggleCart: <Mutation mutation={TOGGLE_CART_MUTATION} />,
createOrder: <Mutation mutation={CREATE_ORDER_MUTATION} />,
});
我的组件看起来像这样。我在此处提供了 planID,但如何将其作为参数传递给 mutation?!
render() {
const { plan } = this.props;
return (
<Composed>
{({ toggleCart, createOrder }) => {
const handleAdd = () => {
toggleCart();
Router.push('/waschingmachine');
createOrder();
};
return (
<StyledPlan>
<h1>{plan.name}</h1>
<p>{plan.description}</p>
<img src={`static${plan.images[0]}`} alt="blue1" />
<h2>{plan.pricePerMonth / 100} EUR</h2>
<div className="buttons">
<Link
href={{
pathname: '/plan',
query: { id: plan.id },
}}
>
<button type="button">info</button>
</Link>
<button onClick={handleAdd} type="button">
Select Plan
</button>
</div>
</StyledPlan>
);
}}
</Composed>
);
}
如果没有办法以这种方式解决,您会如何采用不同的方法?
可以使用选项调用传递给渲染子项的 mutate 函数。
选项可以包括 GraphQL 突变字符串中使用的变量。 [1].
这意味着您可以像这样调用createOrder
变异函数。
createOrder({ variables: { planID: 'some plan id' } });
鉴于 planID 的动态特性,有多种方法可以实现这一点。其中之一是使用如下数据属性:
可以为按钮上的计划 ID 设置 data
属性。
<button onClick={handleAdd} data-planid={plan.id} type="button">
Select Plan
</button>
handleAdd
可以重构为从目标数据集属性中获取 planid
并使用 planID
变量调用 createOrder
。
const handleAdd = event => {
const planID = event.target.dataset.planid;
toggleCart();
Router.push('/waschingmachine');
createOrder({ variables: { planID } });
};
另一种是在按钮的 onClick
属性中调用时直接将 planID
传递给 handleAdd
。
<button onClick={() => handleAdd(plan.id)} type="button">
Select Plan
</button>
然后更新处理程序
const handleAdd = planID => {
toggleCart();
Router.push('/waschingmachine');
createOrder({ variables: { planID } });
};
这两种方法都需要权衡取舍。对于早期的方法,planid 在 DOM 中设置为属性,可以稍后读取。
而对于后一个,为 N 个计划创建 N 个处理程序并保存在内存中。
以下是如何通过 react-adopt
方式将参数传递到内部 mutations 映射器:
// In a nutshell, `react-adopt` allows you to pass props to your `Composed`
// component, so your inner `mapper` can access those props to pass them to
// your <Query> or <Mutation>
// Here's your initial `Composed` component from above
const Composed = adopt({
// `planId` is passed from below via props (see `<ContainerComponent />)
toggleCart: ({ planId, render }) => (
<Mutation mutation={TOGGLE_CART_MUTATION} variables={{ planId }}>{render}</Mutation>,
),
// `planId` is passed from below via props (see `<ContainerComponent />)
createOrder: ({ planId, render })=> (
<Mutation mutation={CREATE_ORDER_MUTATION} variables={{ planId }}>{render}</Mutation>
)
});
// `<ContainerComponent />` will take a plan as its props and passed `planId` to
// the `<Composed />` component
const ContainerComponent = ({ plan }) => (
<Composed planId={plan.id}>
{({ toggleCart, createOrder }) => {
const handleAdd = e => {
e.preventDefault();
toggleCart();
// ...
createOrder();
// ...
};
// Whatever your UI needs you can pass them here via here
return <YourPresentationComponent onClick={handleAdd} />;
}}
</Composed>
)
// Now all you need to do is to pass `plan` from your render() to the
// <ContainerComponent /> (This is the render() where you return your
render() {
const { plan } = this.props;
return <ContainerComponent plan={plan} />
}
希望本文对解决您的问题有所帮助!附带说明一下,您还可以获得先前的 mapper
值并将它们作为参数的一部分传递给下一个映射器 fn ,请参见下文:
const Composed = adopt({
// Here you can retrieve the actual `plan` by using `userId` and pass the result
// into your next children mapper fn to consume
plan: ({ userId, render }) => (
<Query query={GET_PLAN_GRQPHQL} variables={{ userId }}>{render}</Query>
),
// `plan` is actually coming from above <Query /> component
toggleCart: ({ plan, render }) => { //... },
createOrder: ({ plan, render }) => { //...}
});
在我的组件中,我使用 react-adopt 来组合 graphql 查询和突变,这样我的渲染道具就不会变得太乱。我有以下代码:
这是我的突变,它需要一个参数 - planID。
const CREATE_ORDER_MUTATION = gql`
mutation CREATE_ORDER_MUTATION($planID: String!) {
createOrder(planID: $planID) {
planID
name
description
subscriptionType
images
subscriptionType
pricePerMonth
}
}
这是 adopt 函数,它需要进行一些更改,其中之一是 createOrder。 Apollo 的工作方式是我需要在这里将变量 prop 传递给 createOrder 组件。问题是,我此时没有 planID。 planID 仅在实际组件内部可用。
const Composed = adopt({
toggleCart: <Mutation mutation={TOGGLE_CART_MUTATION} />,
createOrder: <Mutation mutation={CREATE_ORDER_MUTATION} />,
});
我的组件看起来像这样。我在此处提供了 planID,但如何将其作为参数传递给 mutation?!
render() {
const { plan } = this.props;
return (
<Composed>
{({ toggleCart, createOrder }) => {
const handleAdd = () => {
toggleCart();
Router.push('/waschingmachine');
createOrder();
};
return (
<StyledPlan>
<h1>{plan.name}</h1>
<p>{plan.description}</p>
<img src={`static${plan.images[0]}`} alt="blue1" />
<h2>{plan.pricePerMonth / 100} EUR</h2>
<div className="buttons">
<Link
href={{
pathname: '/plan',
query: { id: plan.id },
}}
>
<button type="button">info</button>
</Link>
<button onClick={handleAdd} type="button">
Select Plan
</button>
</div>
</StyledPlan>
);
}}
</Composed>
);
}
如果没有办法以这种方式解决,您会如何采用不同的方法?
可以使用选项调用传递给渲染子项的 mutate 函数。 选项可以包括 GraphQL 突变字符串中使用的变量。 [1].
这意味着您可以像这样调用createOrder
变异函数。
createOrder({ variables: { planID: 'some plan id' } });
鉴于 planID 的动态特性,有多种方法可以实现这一点。其中之一是使用如下数据属性:
可以为按钮上的计划 ID 设置 data
属性。
<button onClick={handleAdd} data-planid={plan.id} type="button">
Select Plan
</button>
handleAdd
可以重构为从目标数据集属性中获取 planid
并使用 planID
变量调用 createOrder
。
const handleAdd = event => {
const planID = event.target.dataset.planid;
toggleCart();
Router.push('/waschingmachine');
createOrder({ variables: { planID } });
};
另一种是在按钮的 onClick
属性中调用时直接将 planID
传递给 handleAdd
。
<button onClick={() => handleAdd(plan.id)} type="button">
Select Plan
</button>
然后更新处理程序
const handleAdd = planID => {
toggleCart();
Router.push('/waschingmachine');
createOrder({ variables: { planID } });
};
这两种方法都需要权衡取舍。对于早期的方法,planid 在 DOM 中设置为属性,可以稍后读取。 而对于后一个,为 N 个计划创建 N 个处理程序并保存在内存中。
以下是如何通过 react-adopt
方式将参数传递到内部 mutations 映射器:
// In a nutshell, `react-adopt` allows you to pass props to your `Composed`
// component, so your inner `mapper` can access those props to pass them to
// your <Query> or <Mutation>
// Here's your initial `Composed` component from above
const Composed = adopt({
// `planId` is passed from below via props (see `<ContainerComponent />)
toggleCart: ({ planId, render }) => (
<Mutation mutation={TOGGLE_CART_MUTATION} variables={{ planId }}>{render}</Mutation>,
),
// `planId` is passed from below via props (see `<ContainerComponent />)
createOrder: ({ planId, render })=> (
<Mutation mutation={CREATE_ORDER_MUTATION} variables={{ planId }}>{render}</Mutation>
)
});
// `<ContainerComponent />` will take a plan as its props and passed `planId` to
// the `<Composed />` component
const ContainerComponent = ({ plan }) => (
<Composed planId={plan.id}>
{({ toggleCart, createOrder }) => {
const handleAdd = e => {
e.preventDefault();
toggleCart();
// ...
createOrder();
// ...
};
// Whatever your UI needs you can pass them here via here
return <YourPresentationComponent onClick={handleAdd} />;
}}
</Composed>
)
// Now all you need to do is to pass `plan` from your render() to the
// <ContainerComponent /> (This is the render() where you return your
render() {
const { plan } = this.props;
return <ContainerComponent plan={plan} />
}
希望本文对解决您的问题有所帮助!附带说明一下,您还可以获得先前的 mapper
值并将它们作为参数的一部分传递给下一个映射器 fn ,请参见下文:
const Composed = adopt({
// Here you can retrieve the actual `plan` by using `userId` and pass the result
// into your next children mapper fn to consume
plan: ({ userId, render }) => (
<Query query={GET_PLAN_GRQPHQL} variables={{ userId }}>{render}</Query>
),
// `plan` is actually coming from above <Query /> component
toggleCart: ({ plan, render }) => { //... },
createOrder: ({ plan, render }) => { //...}
});