Search code examples
javascriptreactjsgraphqlapollomutation

Apollo GraphQL Mutation separate loading for every item in list


I have a list of Todos:

  • item1
  • item2
  • item3

Every item has a delete button with the mutation to delete a single item. And every item has spinner with loading from deleteMutation

The problem: Once I press the delete button on a single item, the spinner turns on for every item on the list.

I know the problem here, but don't know how to solve it properly. We can add state for every item of list, and logic for turning on spinner.

But I'm looking for the proper solution here. Maybe is there a way to know, with what params the mutation was called, and I'll add simple code

todos.map(({ id, title }) => (
  <div>
    <p>{title}</p>
    <button onClick={() => deleteMutation({ variables: { id } })}>
      {loading && id === deletedId ? <Spinner color="white" size="sm" /> : Delete}
    </button>
  </div>
))

Solution

  • Problem is using/sharing the same mutation instance, it's state - loading. Next problem - deleting two items in the same time probably impossible.

    Possible solutions:

    • if each item has its own mutation - make it a component (cheap abstraction in react), define mutation inside. A bit redundant, of course - but suitable for more complex items or individual actions.

    • ... or you have to use some flag (state) f.e. itemBeingDeleted before calling mutation (clear in 'onCompleted') to block (disable) other items delete button and display loading in one of them.