enabled
Description: Defines if the useMutation hook is active or not. If this is set to false, the mutate function will not execute the action when called.
- How To: Use
enabledto programmatically control when a mutation should be allowed to run, e.g., based on form validation, user permissions, or the presence of required data.// Correct: Only allow updating the profile if the form is valid and dirtyconst { mutate } = useMutation({enabled: form.isValid && form.isDirty,after: () => toast.success('Profile updated!')});const onSave = () => {// If enabled is false, this call will do nothingmutate(() => api.updateProfile(form.values));}; - Best Practice: While you can also disable the button in the UI, setting
enabled: falsein the hook provides an extra layer of protection and ensures that side effects (likebeforeorafterhooks) are also not triggered if the mutation shouldn't run.// Avoid this: Relying only on UI state to prevent mutationconst { mutate } = useMutation({after: () => console.log('This will run even if button was disabled but clicked via console!')});return <button onClick={() => mutate(action)} disabled={!isValid}>Save</button>;// Instead: Guard the mutation logic itselfconst { mutate } = useMutation({enabled: isValid,after: () => console.log('Protected!')});
Deep Dive: How enabled works step by step
Example:
function DeleteButton({ id, canDelete }) {
const { mutate } = useMutation({
enabled: canDelete,
mutationKey: ['delete', id]
});
return <button onClick={() => mutate(() => api.delete(id))}>Delete</button>;
}
What happens step by step when canDelete is false:
- User clicks the button →
mutate()is called. useMutationchecks theenabledoption → Finds it isfalse.- The action function is ignored →
api.delete(id)is never executed. - No state changes occur →
isLoadingremainsfalse,isDoneremainsfalse. - No lifecycle hooks run →
beforeandafterare skipped. - No network request is made → The
DataClientdoes not initiate any fetch.
What happens step by step when canDelete is true:
- User clicks the button →
mutate()is called. useMutationchecks theenabledoption → Finds it istrue.beforehook executes → If defined in options.- The action function is executed →
api.delete(id)starts the network request. isLoadingbecomestrue→ Component re-renders (if not using suspense).- Mutation completes →
isLoadingbecomesfalse,isSuccessorisErroris set. afterhook executes → Receives the response or error.
Key insight: enabled acts as a circuit breaker for the mutate function. It is particularly useful for preventing accidental mutations in complex UIs where multiple conditions must be met.