When working with React Query for data processing, you frequently encounter scenarios where you need to depend on the results of one mutation to execute another mutation. This typically involves chained asynchronous operations, and React Query provides an elegant solution for handling such cases.
Step 1: Define Mutations Using useMutation
First, define each mutation using the useMutation hook. For example, consider two API requests: createUser and sendWelcomeEmail, where sendWelcomeEmail depends on the result of createUser.
javascriptimport { useMutation } from 'react-query'; const createUser = async (userData) => { const response = await fetch('/api/users', { method: 'POST', body: JSON.stringify(userData), headers: { 'Content-Type': 'application/json', }, }); if (!response.ok) { throw new Error('Error creating user'); } return response.json(); }; const sendWelcomeEmail = async (userId) => { const response = await fetch(`/api/users/${userId}/send-email`, { method: 'POST', }); if (!response.ok) { throw new Error('Error sending email'); } return response.json(); }; const createUserMutation = useMutation(createUser); const sendEmailMutation = useMutation(sendWelcomeEmail);
Step 2: Chain Mutations
Next, invoke sendEmailMutation.mutate within the onSuccess callback of createUserMutation. The onSuccess callback triggers after the first mutation completes successfully, ensuring the correct data is passed to the second mutation.
javascriptcreateUserMutation.mutate(userData, { onSuccess: (data) => { // data is the user data returned by createUser, which includes userId sendEmailMutation.mutate(data.userId); }, });
Example: Create User and Send Welcome Email
The following is an integrated component example:
javascriptimport React from 'react'; import { useMutation } from 'react-query'; function CreateUserComponent() { const createUserMutation = useMutation(createUser); const sendEmailMutation = useMutation(sendWelcomeEmail); const handleCreateUser = async (userData) => { createUserMutation.mutate(userData, { onSuccess: (data) => { sendEmailMutation.mutate(data.userId); }, }); }; return ( <div> <button onClick={() => handleCreateUser({ name: 'Alice', email: 'alice@example.com' })}> Create User and Send Email </button> </div> ); }
In this example, clicking the button triggers handleCreateUser, which executes the user creation operation. Upon success, it uses the new user's ID to execute the welcome email sending operation. This approach ensures the order and dependency of operations, with a clear and maintainable code structure.
Summary
Using React Query's useMutation with the onSuccess callback effectively manages multiple dependent asynchronous operations, ensuring they execute in the correct sequence and handle data dependencies between them. This pattern not only makes the code easy to understand and maintain but also optimizes user experience and application performance.