反应阿波罗 - 突变时的奇怪效果?



>我已经用React-Apollo建立了一个React应用程序,可以成功查询我的API。

但是,当我进行突变时,会发生奇怪的效果。我成功取回了所有数据(如Chrome开发工具的"网络"选项卡中所示(,但是在尝试console.log数据时,它说它是null

以下是相关代码:

// mutation file
import gql from "graphql-tag";
export default gql`
mutation CreateReservation($name: String!, $time: String!, $persons: String, $specialMessage: String, $email: String!) {
createReservation(input: {
name: $name,
time: $time,
persons: $persons,
specialMessage: $specialMessage,
email: $email
}) {
__typename
error
data
}
}
`;
// component file
import React from "react";
import {graphql, compose} from "react-apollo";
import CreateReservationMutation from "../../graphql/mutations/api/CreateReservation";
class Reservations extends React.Component {
testGraphQL = ({ reservationName, reservationTime, reservationEmail, reservationPartySize, reservationMessage}) => {
const variables = {
name: reservationName,
time: reservationTime,
persons: reservationPartySize,
specialMessage: reservationMessage,
email: reservationEmail
};
this.props.createReservation(variables)
.then(({data}) => {
console.log("Data received: ", data); // Here is the problem
}).catch((err) => {
console.log("Error sending data: ", err);
})
}
render() {
return (
<div>
...
<div>
<Form 
...
submitFunc={this.testGraphQL}
/>
</div>
...
</div>
</div>
)
}
}
export default compose(
graphql(CreateReservationMutation, {
props: ({mutate}) => ({
createReservation: (variables) => mutate({variables})
})
})
)(Reservations);

因此,当我调用testGraphQL函数时,我在控制台中收到以下内容:

Data received:  {createReservation: null}

但是在"网络"选项卡中查看时,我看到数据实际上毕竟存在,并且正是我正在寻找的。此外,我的数据库已正确更新了所有预订详细信息,因此我可以肯定地知道正在执行突变。

这是我从"网络"选项卡中看到的内容:

{"data":{"createReservation":{"__typename":"ReservationResponse","error":null,"data":"Success"}}}

这就是我在testGraphQL打电话给console.log时所期望看到的。

所以我知道我的架构、我的 Apollo 客户端或我的突变文件没有任何错误。

相反,问题必须在于我如何设置我的compose语句或我如何称呼突变本身。

如果您在这里发现错误,请告诉我。谢谢

更新

我应该提到,我正在使用 AWS AppSync 作为我的 GraphQL 提供程序。

突变调用 lambda 函数,该函数执行以下操作:

...
Promise.all([dynamodbPromise, snsPromise, sesPromise])
.then((data) => {
callback(null, {data: "Success"});
})
.catch((err) => {
callback(null, {error: err});
});

这是我对这种突变的解析器:

// request mapping template
{
"version" : "2017-02-28",
"operation": "Invoke",
"payload": $util.toJson($ctx.args.input)
}
//  response mapping template
$util.toJson($context.result)

更新 2

配置一个optimisticResonse并像这样重写我的突变:

this.props.createReservation({
variables,
optimisticResponse: {
createReservation: {
__typename: "ReservationResponse",
errorMessage: null,
responseMessage: "_TEST_"
}
}
})
.then(res => {
console.log("Apllo Data: ", res);
})

导致我只从乐观响应中获取数据,即:

{data:
createReservation: {
__typename: "ReservationResponse", 
errorMessage: null, 
responseMessage: "Optimistic Success"
}

因此,返回的数据不得使用 API 的实际响应进行更新。

现在如何强制阿波罗在返回乐观响应后更新响应?

有两个选项可以从突变中获取数据响应:

在突变组件中:

<Mutation>{mutation, {data}}</Mutation>

或者在突变函数中:

mutate().then(data => ...)

您正在获得突变承诺响应,但您期望 apollo 传递给突变组件的状态对象。

apollo 传递状态对象是没有意义的,因为如果突变解析成功,任何错误都会使承诺被拒绝,并且在突变调用期间不提供加载状态。

所以要修复你的代码,你只需要改变这个

this.props.createReservation(variables)
.then(data => {

我终于解决了它,尽管解决方案不太理想。

我不得不为我的突变编写一个更新函数。这是一个准系统实现,最终为我提供了来自 API 的实际数据:

this.props.createReservation({
variables,
optimisticResponse: {
createReservation: {
__typename: "ReservationResponse",
errorMessage: null,
responseMessage: "Optimistic Success"
}
},
update: (proxy, {data: {createReservation}}) => {
console.log("Update: ", createReservation);
}
})
.then(res => {
console.log("Apllo Data: ", res);
})

更新函数被调用三次。在解决承诺之前,前两次触发,包括来自optimisticResponse的数据,如我的"更新 2"部分所示。第三次调用最终从 API 返回实际数据。

虽然这暂时有效,但请让我知道这里是否有更直接的方法。在这种情况下,我根本不希望返回optimisticResponse。我只想返回来自我的 API 的实际数据。这样,我可以在出现问题时为用户提供适当的错误处理。

谢谢,我希望我们可以帮助其他有这个问题的人。

只需使用res.data即可访问返回的属性

this.props.createReservation({
variables,
optimisticResponse: {
createReservation: {
__typename: "ReservationResponse",
errorMessage: null,
responseMessage: "_TEST_"
}
}
})
.then(res => {
console.log("Apllo Data: ", res.data);
})

最新更新