Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Run a callback before the internal state of useMutation is updated. #415

Open
joeprivettsmart opened this issue Jan 11, 2024 · 0 comments
Open
Labels
🪝 react hooks Feature requests related to React hooks

Comments

@joeprivettsmart
Copy link

Problem:
In the useMutation hook the internal state is updated before onCompleted method is executed:
https://github.com/apollographql/apollo-client/blob/57e9dae68762be10087fbe310c00ff7e4d0f7259/src/react/hooks/useMutation.ts#L125

In React, when we need to re-direct to another page following a successful mutation result, the following code can be used:

const [mutateFunction, { loading }] = useMutation(SOME_MUTATION, {
  onCompleted: () => {
    redirectTo('/foo')
  },
});

However, the redirectTo method is called after the internal loading state of the useMutation hook is updated. This causes the host React Component to re-render before re-directing, showing a flash of undesired content on the screen before the new page is reached.

Solutions:
Introduce a beforeCompletes or onSuccess method. This is run before any internal state is updated. If it returns false, then it prevents any subsequent internal state update and does not execute onCompleted.

For example:

let onSuccessResult;
if (!error) {
  onSuccessResult = onSuccess?.(
    response.data!,
    clientOptions as MutationOptions<TData, OperationVariables>
  );
}

if (
  onSuccessResult !== false && 
  mutationId === ref.current.mutationId &&
  !clientOptions.ignoreResults
) {
  const result = {
    called: true,
    loading: false,
    data,
    error,
    client,
  };

  if (ref.current.isMounted && !equal(ref.current.result, result)) {
    setResult((ref.current.result = result));
  }
}

const onCompleted =
  executeOptions.onCompleted || ref.current.options?.onCompleted;

if (onSuccessResult !== false && !error) {
  onCompleted?.(
    response.data!,
    clientOptions as MutationOptions<TData, OperationVariables>
  );
}

return response;
@jerelmiller jerelmiller added the 🪝 react hooks Feature requests related to React hooks label Jan 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🪝 react hooks Feature requests related to React hooks
Projects
None yet
Development

No branches or pull requests

2 participants