React-apollo: useMutation hook not re-rendering with optimisticResponse

Created on 5 Jul 2019  ·  10Comments  ·  Source: apollographql/react-apollo

Intended outcome:

Re-render the component when an optimisticResponse is given to useMutation

Actual outcome:

The optimistic response isn't used

How to reproduce the issue:

I forked a codesandbox that was using Apollo hooks, added an optimisticResponse to it. You will notice it does not rerender immediately with it, only renders after the real response comes back. https://codesandbox.io/s/apollo-graphql-react-hooks-example-sz66s

The mutation code is here:

https://github.com/apollographql/react-apollo/blob/1a69cd244910b801176550a7137baf570c836516/packages/hooks/src/data/MutationData.ts

But I think a change is probably needed in the useQuery somehow?

Version

"@apollo/react-hooks": "0.1.0-beta.10"

Most helpful comment

Holy hell that was it. I wasted time making a repro 😂 → https://github.com/deadcoder0904/test-optimistic-ui

Tysm 🙌

All 10 comments

I experience same issue with a mutation update.
While the data is updated in apollo dev tools - the relevant query does not trigger a re-render.

Thanks for reporting this issue and the reproduction @zackify. Your reproduction is missing a small detail that makes it look like optimisticResponse isn't working. If you change your MARK_FAVORITE_MUTATION query to include institution in the result selection set

const MARK_FAVORITE_MUTATION = gql`
  mutation markFavoriteTeam($id: Int!) {
    markFavoriteTeam(id: $id) {
      id
      institution
    }
  }
`;

you should see the University of Maryland result change to TESTTTTT before the proper results are loaded.

Let me know if you still notice any issues after making his change.

I'll add an additional test or 2 to our test suite to show that things are working as intended. Thanks!

Good catch. I will have to go look at my app again because I swear it wasn't using the optimistic response. I will make a repro of it right now if I can get it to happen

Sounds good @zackify - I'll close this for now, but if you notice more issues with this, definitely post back and I'll re-open. Thanks!

In my app, when I log the query result in render, it only renders one time after a mutation update, unlike the code sandbox. My guess is something to do with updating a nested type.

Ex: my query returns a top level type that then has the thing im updating nested inside it. This is the only difference I can find with the codesandbox vs my code.

Is there any example graphql api that I can use or should i try to write a test case in this repo?

Good news, with the 3.0.0 release it started working as expected!

i try.

Hey @hwillson & @zackify I'm facing the same issue with latest Apollo Hooks (v3.1.1)

My code looks like -

import { ApolloProvider, useMutation, useQuery } from '@apollo/react-hooks'
import ApolloClient, { gql } from 'apollo-boost'
import React from 'react'

const client = new ApolloClient({
  uri: 'http://localhost:4000',
  connectToDevTools: true,
})

const BLOGS_QUERY = gql`
  query blogs {
    blogs {
      id
      published
    }
  }
`

const PUBLISH_BLOG_MUTATION = gql`
  mutation publishBlog($id: ID, $published: Boolean) {
    publishBlog(id: $id, published: $published) {
      id
    }
  }
`

const Blog = () => {
  const { loading, error, data } = useQuery(BLOGS_QUERY)
  const [publishBlog] = useMutation(PUBLISH_BLOG_MUTATION)

  if (loading) return <div>Loading...</div>
  if (error) return <div>Error</div>
  return (
    <div>
      <h1>Blog</h1>
      {data.blogs.map(item => {
        return (
          <div key={item.id}>
            <button
              onClick={() => {
                publishBlog({
                  variables: {
                    id: item.id,
                    published: !item.published,
                  },
                  optimisticResponse: {
                    __typename: 'Mutation',
                    publishBlog: {
                      __typename: 'Blog',
                      id: 1,
                      published: true,
                    },
                  },
                })
              }}
            >
              {item.published ? 'Published' : 'Not yet'}
            </button>
          </div>
        )
      })}
    </div>
  )
}

function App() {
  return (
    <ApolloProvider client={client}>
      <Blog />
    </ApolloProvider>
  )
}

export default App

This is the minimal reproduction I could produce. I don't know why it isn't working because I think that looks pretty similar to yours.

AFAIK response from the original mutation is put in optimisticResponse with 2 __typename so I'm doing exactly that.

Any ideas?

Have you tried adding “published” to the mutation gql tag. You only have ID there. That would be my first guess

Holy hell that was it. I wasted time making a repro 😂 → https://github.com/deadcoder0904/test-optimistic-ui

Tysm 🙌

Was this page helpful?
0 / 5 - 0 ratings