Howtographql: React-Apollo: UI fails to re-render after cache.writeQuery

Created on 22 Sep 2019  路  6Comments  路  Source: howtographql/howtographql

https://github.com/howtographql/howtographql/blob/cd55823a5bd72ec17d48e2996b04c7d4260761fe/content/frontend/react-apollo/6-more-mutations-and-updating-the-store.md#L320

In this section, it is stated that the UI will reflect the changes of the mutation, but unfortunately that is not the case, not unless I perform a forceUpdate on the LinkList component.

Apollo Doc - Cache

This section states that a client.writeQuery() instead performs that re-render, but even that failed for me.

Looking for any possible explanations/suggestions. Thanks! :slightly_smiling_face:

Most helpful comment

@V1shvesh, the vote object passed to this.props.updateStoreAfterVote is the result of the query against the Vote Type returned by the vote mutation, defined in VOTE_MUTATION.
inside _updateCacheAfterVote, link.id is required to find the correct link to update in the store.
so adding id to link fields fixed it for me:

const VOTE_MUTATION = gql`
  mutation VoteMutation($linkId: ID!) {
    vote(linkId: $linkId) {
      link {
        id
        votes {
          id
          user {
            id
            name
          }
        }
      }
      user {
        id
        name
      }
    }
  }
`;

All 6 comments

@V1shvesh, the vote object passed to this.props.updateStoreAfterVote is the result of the query against the Vote Type returned by the vote mutation, defined in VOTE_MUTATION.
inside _updateCacheAfterVote, link.id is required to find the correct link to update in the store.
so adding id to link fields fixed it for me:

const VOTE_MUTATION = gql`
  mutation VoteMutation($linkId: ID!) {
    vote(linkId: $linkId) {
      link {
        id
        votes {
          id
          user {
            id
            name
          }
        }
      }
      user {
        id
        name
      }
    }
  }
`;

@grahamcn Thanks for taking the time to solve this! Shall any one of us submit a PR to fix the same?

@V1shvesh no problem! yeah good idea, i can look at that 馃憤

@V1shvesh, the vote object passed to this.props.updateStoreAfterVote is the result of the query against the Vote Type returned by the vote mutation, defined in VOTE_MUTATION.
inside _updateCacheAfterVote, link.id is required to find the correct link to update in the store.
so adding id to link fields fixed it for me:

const VOTE_MUTATION = gql`
  mutation VoteMutation($linkId: ID!) {
    vote(linkId: $linkId) {
      link {
        id
        votes {
          id
          user {
            id
            name
          }
        }
      }
      user {
        id
        name
      }
    }
  }
`;

Hi @grahamcn ! Your solution fixed the issue but I am having a hard understanding why did it fix the issue? I mean we aren't even using that particular id field anywhere then how does it cause re-render?

hi @anku255, we're using that id to update the correct link in the cache after the vote has been placed - as i understand it, the re-render would be caused by the mutated link data in the cache.

hi @anku255, we're using that id to update the correct link in the cache after the vote has been placed - as i understand it, the re-render would be caused by the mutated link data in the cache.

Well, the function_updateCacheAfterVote takes three arguments store, createVote, and linkId.
The id field that we added in the Mutation would be referenced by createVote.link.id but we only seem to be using createVote.link.votes.

As far as finding and updating the correct link is concerned, we are doing that using linkId argument and this doesn't come from the Mutation response but rather from the prop that was passed during render.

_updateCacheAfterVote = (store, createVote, linkId) => {
  const data = store.readQuery({ query: FEED_QUERY })

  // linkId is used for finding the correct link
  const votedLink = data.feed.links.find(link => link.id === linkId)
  votedLink.votes = createVote.link.votes

  store.writeQuery({ query: FEED_QUERY, data })
}

Can you please help me understand how the createVote.link.id is being used here, which causes the re-render?

Was this page helpful?
0 / 5 - 0 ratings