The React Query library lets us make HTTP requests easily in our React apps.
In this article, we’ll look at how to commit side effects in React Query mutations?
Mutation Side Effects
We can watch for events that are emitted when mutations are being committed.
For instance, we can write:
import axios from "axios";
import React, { useState } from "react";
import { useMutation } from "react-query";
export default function App() {
const { reset, mutate } = useMutation(
(data) => axios.post("https://jsonplaceholder.typicode.com/posts", data),
{
onMutate: (variables) => {
console.log(variables);
return {};
},
onError: (error, variables, context) => {
console.log(error, variables, context);
},
onSuccess: (data, variables, context) => {
console.log(data, variables, context);
},
onSettled: (data, error, variables, context) => {
console.log(data, error, variables, context);
}
}
);
const [title, setTitle] = useState("");
const onCreateTodo = (e) => {
e.preventDefault();
mutate({
title
});
};
return (
<div>
<form onSubmit={onCreateTodo}>
<input
type="text"
value={title}
onChange={(e) => setTitle(e.target.value)}
/>
<br />
<button type="submit">Create Todo</button>
<button type="button" onClick={() => reset()}>
reset
</button>
</form>
</div>
);
}
The onMutate
method is run when the mutation request is being made.
variables
has the mutation data from the data
parameter.
onError
is run when there’s an error with the mutation.
error
has the error object.
variables
is the same as before.
context
has the context data which has the mutation request data.
onSuccess
is run when the mutation request is successful.
data
has the mutation response data.
variables
and context
are the same as the other callback parameters.
onSettled
is run whenever a mutation request is finished regardless of whether it’s successful or not.
All the parameters are the same as before.
We can also add the same callbacks to the mutate
method call.
For instance, we can write:
import axios from "axios";
import React, { useState } from "react";
import { useMutation } from "react-query";
export default function App() {
const { reset, mutate } = useMutation(
(data) => axios.post("https://jsonplaceholder.typicode.com/posts", data),
{
onMutate: (variables) => {
console.log(variables);
return {};
},
onError: (error, variables, context) => {
console.log(error, variables, context);
},
onSuccess: (data, variables, context) => {
console.log(data, variables, context);
},
onSettled: (data, error, variables, context) => {
console.log(data, error, variables, context);
}
}
);
const [title, setTitle] = useState("");
const onCreateTodo = (e) => {
e.preventDefault();
mutate(
{
title
},
{
onMutate: (variables) => {
console.log(variables);
return {};
},
onError: (error, variables, context) => {
console.log(error, variables, context);
},
onSuccess: (data, variables, context) => {
console.log(data, variables, context);
},
onSettled: (data, error, variables, context) => {
console.log(data, error, variables, context);
}
}
);
};
return (
<div>
<form onSubmit={onCreateTodo}>
<input
type="text"
value={title}
onChange={(e) => setTitle(e.target.value)}
/>
<br />
<button type="submit">Create Todo</button>
<button type="button" onClick={() => reset()}>
reset
</button>
</form>
</div>
);
}
The callbacks we add to the object we pass in as the 2nd argument of mutate
will run after the callbacks we added to the useMutation
hook.
Conclusion
We can add callbacks to the object we pass into the useMutation
hook or mutate
method to watch for any events that are triggered when making our mutation request with React Query.