So taking a look at the Apollo useMutation example in the docs https://www.apollographql.com/docs/react/data/mutations/#tracking-loading-and-error-states
function Todos() {
...
const [
updateTodo,
{ loading: mutationLoading, error: mutationError },
] = useMutation(UPDATE_TODO);
...
return data.todos.map(({ id, type }) => {
let input;
return (
<div key={id}>
<p>{type}</p>
<form
onSubmit={e => {
e.preventDefault();
updateTodo({ variables: { id, type: input.value } });
input.value = '';
}}
>
<input
ref={node => {
input = node;
}}
/>
<button type="submit">Update Todo</button>
</form>
{mutationLoading && <p>Loading...</p>}
{mutationError && <p>Error :( Please try again</p>}
</div>
);
});
}
This seems to have a major flaw (imo), updating any of the todos will show the loading state for every single todo, not just the one that has the pending mutation.
And this seems to stem from a larger problem: there's no way to track the state of multiple calls to the same mutation. So even if I did want to only show the loading state for the todos that were actually loading, there's no way to do that since we only have the concept of "is loading" not "is loading for todo X".
Besides manually tracking loading state outside of Apollo, the only decent solution I can see is splitting out a separate component, use that to render each Todo instead of having that code directly in the Todos component, and having those components each initialize their own mutation. I'm not sure if I think that's a good or bad design, but in either case it doesn't feel like I should have to change the structure of my components to accomplish this.
And this also extends to error handling. What if I update one todo, and then update another while the first update is in progress. If the first call errors, will that be visible at all in the data returned from useMutation? What about the second call?
Is there a native Apollo way to fix this? And if not, are there options for handling this that may be better than the ones I've mentioned?
Code Sandbox: https://codesandbox.io/s/v3mn68xxvy

mutationLoading. state that you pass to your todos. the same state gets passed to all of them, so even if apollo had something you want, your code still wouldn't be making use of it. it would have to be something likeloadingId === idat the very least. Anyways your problem is completely solved by callinguseMutationat the item level, not the list level. that's not a workaround, it's perfectly sane solution - aziumisLoadingwith the knowledge of which variable was being passed to the mutation, though I would consider that to be a much worse solution - aziumloadingId === id, butloadingIdisn't available. - Westonloadingwould mean nothing if I don't know exactly which mutations are the ones actuallyloading. - WestonTodoscomponent (for some reason) I would either lose that ability, or need to add some sort ofonLoadingcallback to theTodocomponents, and still manually keep track of loading state inTodos. - Weston