useMutation hangs

I’ve the following code:

create: (input: MutationInput) => {
        const [mutationFn, { loading, error, data }] = useMutation(CREATE)
        mutationFn({variables: {input}})
        return { loading, error, data }
    }

which is called within a component, however, calling the create function hangs and doesn’t return a response.

Adding console logging, I can see that I can log before useMutation is called, but not after. Am I using useMutation incorrectly?

Can you share a bit more code?

Generally useMutation can only be used in the main body of a React component (like every hook), and this doesn’t really look like a component to me - but without more context it’s hard to say.

@lenz

const ComponentApi = {
    list: () => useQuery(GET_ALL_COMPONENTS),
    create: (input: CreateComponentMutationInput) => {
        const [mutationFn, { loading, error, data }] = useMutation(CREATE_COMPONENT)
        mutationFn({variables: {input}})
        return { loading, error, data }
    }
}

and it’s called in a component:

<Form<CreateComponent>
			onSubmit={async (input) => {
				const dto = {
					name: input.name,
					typeReference: input.type?.value,
					description: input.description,
					attributes: {},
					tierLevel: (input.tierLevel?.value || 1) as number,
				}

				const {loading, data, error} = ComponentApi.create(dto)

				if (!loading) {
					createFunction(data?.newComponent?.entityReference!, typeof error !== 'undefined')
				}
			}}
		>

Even if I call it inside the component, the same behaviour is exhibited:

<Form<CreateComponent>
			onSubmit={async (input) => {

				const dto = {
					name: input.name,
					typeReference: input.type?.value,
					description: input.description,
					attributes: {},
					tierLevel: (input.tierLevel?.value || 1) as number,
				}

				// const {loading, data, error} = ComponentApi.create(dto)

				const [mutationFn, { loading, error, data }] = useMutation(CREATE_COMPONENT)

				mutationFn({variables: {input: dto}})

				if (!loading) {
					createFunction(data?.newComponent?.entityReference!, typeof error !== 'undefined')
				}
			}}
		>

You are not calling it “in a component” - you call it in a callback.

For useMutation, the same rules as for all other React hooks (like useState, useRef, useMemo etc.) apply:

The have to be part of the component render. Not a callback or anything.

So

function MyComponent(){
  const [trigger, returnValue] = useMutation(CREATE_COMPONENT)
  function onClick() {
    trigger()
  }
}

is a valid usage of a hook.

function MyComponent(){

  function onClick() {
    const [trigger, returnValue] = useMutation(CREATE_COMPONENT)
  }
}

is not a valid usage of a hook.

Please see Rules of Hooks – React to learn how you can or cannot use hooks.