如何在使用表单组件时在 apollo-client 中链接突变
Posted
技术标签:
【中文标题】如何在使用表单组件时在 apollo-client 中链接突变【英文标题】:How to chain mutations in apollo-client while using a form component 【发布时间】:2019-06-17 11:48:17 【问题描述】:阿波罗客户端 2.0。我正在使用链式突变组件。我正在尝试将第一个 Mutation 的返回值传递给第二个 Mutation。当单击表单组件上的 onSubmit 按钮时,我执行突变。第一个突变的返回值没有作为第二个突变中的“变量”之一传递
我在两个非常相似的帖子中查看了解决方案:How to wrap GraphQL mutation in Apollo client mutation component in React 和 How to chain together Mutations in apollo client。我认为我对表单的使用为我的解决方案增加了一些额外的复杂性。尽管传递的值(competitionId)在 handleOnSubmit 函数中可见(如果我在 handleOnSubmit 中的 createCompetition() 之后进行控制台日志),但它不会作为在 handleOnSubmit 中调用的第二个 Mutation 中的变量传递。结果是第一个 Mutation 成功执行,第二个 Mutation 出现 400 错误:“errors”:[“message”:“Variable \“$competitionId\” of required type \“ID!\”没有提供。 ”更具体地说, CompetitionId 的值在第一个突变运行后会传递给第二个突变,但它不会作为“变量”传递给作为参数传递给 handleOnSubmit 的 createMatch 函数。看起来与 createMatch 函数一起传递给 handleOnSubmit 的“变量”仅包括单击提交按钮时可用的变量。在点击提交按钮后生成competitionId,第一个mutation将其作为结果返回。
handleOnSubmit = async(event, createCompetition, createMatch) =>
event.preventDefault();
await createCompetition();
await createMatch();
this.clearState();
this.props.history.push('/home');
render ()
const location, name, action, caliber, rifleName, dateOf,competitionScore = this.state;
const matchNumber, targetNumber, relay, distanceToTarget, matchScore = this.state;
return (
<div className="App">
<h2 className="App">Add Competition</h2>
<Mutation
mutation=CREATE_COMPETITION
variables=location, name, action, caliber, rifleName, dateOf, competitionScore
refetchQueries=() => [
query: GET_ALL_COMPETITIONS, variables:name: name
]
update=this.updateCache>
(createCompetition, data, loading, error) =>
if(loading) return <div>loading competition...</div>
if(error) return <div>error: error</div>
let competitionId;
if(data)
competitionId = data.createCompetition._id;
return (
<Mutation
mutation=CREATE_MATCH
variables=competitionId, matchNumber, targetNumber, distanceToTarget, matchScore>
(createMatch, _, loading, error) =>
if(loading) return <div>loading match...</div>
return (
<form
className="form"
onSubmit=event => this.handleOnSubmit (event, createCompetition, createMatch)>
<label> remaining form deleted for brevity
我希望 CompetitionId 的值作为变量传递给在 handleOnSubmit 方法中调用的 createMatch 函数。没有提供。
【问题讨论】:
【参考方案1】:看来你需要的是嵌套突变 :thinkingface;
问:你在使用 prisma 吗?
嗯,在 GraphQL 中,您可以通过单个突变创建节点,如果您的类型相关,这非常简单,所以我假设这是您的情况。
看起来应该是这样的:
datamodel.graphql
type Competition
id: ID! @unique
name: String!
match: Match! @relation(name: "CompetitionMatch")
type Match
id: ID! @unique
name: String!
campetition: Competition! @relation(name: "CompetitionMatch")
所以,现在你的schema.graphql
应该是这样的:
type Mutation
createCompetition (name: String! match: MatchInput): Competition
input MatchInput
name: String!
现在当您调用 createCompetition
突变时,您必须发送匹配数据,如下所示:
mutation createCompetition (
name: 'Loremp competition'
match: name: 'child match'
)
id
name
match
id
name
参考:https://www.graph.cool/docs/reference/graphql-api/mutation-api-ol0yuoz6go/#nested-create-mutations
希望对您有所帮助!
问候
【讨论】:
我没有使用棱镜。我更愿意继续使用 Apollo-Server 2 和 mongoose。一旦我更好地理解了 Apollo-Server/Client,我可能会尝试 prisma。您对我的类型相关的假设是正确的并且查询工作正常,这是一个挑战: type Competition _id: ID name: StringrifleName: String location: String action: String caliber: Float dateOf: String CompetitionScore: String匹配:[匹配] `; 我通过在后端编写一个支持模式的更复杂的突变解决了这个问题。然后我所要做的就是调用单个突变,不需要链接。我收到了在我们当地的 React MeetUp 上尝试这种技术的建议。在研究了这一点后,我将 Apollo 文档中提供的指导铭记于心。该指导是您应该根据客户如何最好地使用数据来编写特定的突变/查询。我在后端 API 上编写了一个突变,创建了一个比赛、3 场比赛和 60 次投篮。【参考方案2】:如果(数据)在哪里,你应该在哪里返回第二个突变
【讨论】:
以上是关于如何在使用表单组件时在 apollo-client 中链接突变的主要内容,如果未能解决你的问题,请参考以下文章
在 Apollo-client 中,writeQuery 会更新缓存,但 UI 组件不会重新渲染
GraphQL _ Apollo-client - 直接在组件中传递 guery 变量