Search code examples
reactjsgraphqlapolloreact-apolloapollo-client

How do I reset the useMutation hook of Apollo Client


I am developing a React form that's tied to a GraphQL mutation using the useMutation of Apollo Client. On the server, I perform some validation and in case of errors, I reject the mutation. On the client-side, I use the error object to receive the validation errors. My hook looks like this:

const [addDrone, { error }] = useMutation(ADD_DRONE)

So I unpack the error object and present it to the user in a dialog to let him/her know what went wrong. After the user dismisses the dialog, I want to give the user a chance to fix the error so he/she can resubmit the form. This is where things get hairy. I want to clear the error object when the user dismisses the dialog, but since this variable comes from the useMutation hook there is no way for me to mutate or reset it. It looks like the useMutation was designed to be fired once, and not used again.

So my question is, is there a way to "reset" a useMutation hook back to it's original state?


Solution

  • UPDATE 12/22/2021: As of version 3.5.0 of @apollo/client the useMutation hook now provides a reset method. You can use this method to reset the hook back to its initial state. E.g.:

    const [addDrone, { error, reset }] = useMutation(ADD_DRONE)
    

    Below are some notes from the official documentation on this method.

    Call reset to reset the mutation's result to its initial state (i.e., before the mutate function was called). You can use this to enable users to dismiss mutation result data or errors in the UI.

    Calling reset does not remove any cached data returned by the mutation's execution. It only affects the state associated with the useMutation hook, causing the corresponding component to rerender.


    Old answer, kept for those who use an older version of @apollo/client:

    As of 12/26/2020 there's no way to reset a useMutation, however there are two feature requests #157 #170 on the Apollo Feature Request repo asking for one, so this may change in the future.

    The easiest way to implement this behavior right now is to drop the error variable and use the onError handler instead. This is a callback provided by useMutation which uses the same error object. You can then wire that to your own stateful variable, which gives you the exact same error variable and the ability to use setError to clear it. See this example below:

      const [error, setError] = React.useState(null)
      const [addDrone] = useMutation(ADD_DRONE, {
        onError: setError,
      })
    

    If you're looking to reset the data object as well you can introduce another stateful tuple [data, setData] and wire the setData to the onCompleted callback.