Reactjs/Apollo/AppSync Mutation Optimistic Respons

2020-08-03 05:30发布

问题:

So first off I will start by saying I added an optimistic response to my mutation so it would it stop producing duplicates as referenced here and from this previous S.O. question.

So that is all working but I have a set of dependant mutations that run after the first using async await.

  submitForm = async () => {
    // Only submit if form is complete
    if (!this.state.saveDisabled) {
      try {
        // Optimistic Response is necessary because of AWS AppSync
        // https://stackoverflow.com/a/48349020/2111538
        const createGuestData = await this.props.createGuest({
          name: this.state.name,
        })
        let guestId = createGuestData.data.addGuest.id

        for (let person of this.state.people) {
          await this.props.createPerson({
            variables: {
              name: person.name,
              guestId,
            },
            optimisticResponse: {
              addPerson: {
                id: -1, // A temporary id. The server decides the real id.
                name: person.name,
                guestId,
                __typename: 'Person',
              },
            },
          })
        }

        this.setState({
          redirect: true,
        })
      } catch (e) {
        console.log(e)
        alert('There was an error creating this guest')
      }
    } else {
      Alert('Please fill out guest form completely.')
    }
  }

Now this works and it is using the same pattern for the mutation as per the sample project

export default compose(
  graphql(CreateGuestMutation, {
    name: 'createGuest',
    options: {
      refetchQueries: [{ query: AllGuest }],
    },
    props: props => ({
      createGuest: guest => {
        console.log(guest)
        return props.createGuest({
          variables: guest,
          optimisticResponse: () => ({
            addGuest: {
              ...guest,
              id: uuid(),
              persons: [],
              __typename: 'Guest',
            },
          }),
        })
      },
    }),
  }),
  graphql(CreatePersonMutation, {
    name: 'createPerson',
  }),
)(CreateGuest)

The only problem is that I can't force the state to get updated to the ID that actually gets inserted when using Async Await, so all the person entries get the place holder UUID. Note, I have also tried using id: -1 as is done with the createPerson mutation but that didn't change anything, it just used negative one for all the entires.

Is there a better way of doing this? I am doing something wrong. This all worked without the optimisticResponse but it always created two entries per mutation.

回答1:

Can you try this again? There were enhancements to the AppSync SDK for Javascript which no longer require you to use Optimistic Response. You can use it optionally if you still want an optimistic UI.

Additionally you can also now disable offline if that's not a requirement for your app by using disableOffline like so:

const client = new AWSAppSyncClient({
    url: AppSync.graphqlEndpoint,
    region: AppSync.region,
    auth: {
        type: AUTH_TYPE.API_KEY,
        apiKey: AppSync.apiKey,
    },
    disableOffline: true
});