React Apollo - 突变时的奇怪效果?

IT技术 reactjs promise graphql apollo react-apollo
2021-05-21 05:32:32

我已经使用 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"}}}

这就是我希望看到,当我打电话console.logtestGraphQL

所以我知道我的模式、我的 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 的实际响应进行更新。

在返回乐观响应后,我现在如何强制 Apollo 更新响应?

3个回答

您有两种选择可以从突变中获取数据响应:

在 Mutation 组件中:

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

或者在变异函数中:

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

您正在获得 mutate Promise响应,但您期望 apollo 传递给 Mutation 组件的状态对象。

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

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

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);
    })

更新函数被调用 3 次。Promise解决之前的前两个触发,包括来自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);
})