DEV Community

Cover image for How to use 'useMutation' in React Query
aravind_akay
aravind_akay

Posted on • Edited on

How to use 'useMutation' in React Query

I'm pretty sure you've read my previous post about how to get started with react-query where I discuss how to use 'useQuery' hook on fetching the data.

So 'useQuery' is only used for fetching the data but 'useMutation' is for post/put request to the backend.

Lets say I have a function for post request.

In userApi.js
import axios from 'axios'


const api = axios.create({
    baseURL : "https://gorest.co.in/public/v2",
    headers : {'Authorization' : `Bearer ${apiToken}`}
}


export const createUser = (newUser) => api.post("/users",newUser).then(res => res.data);
Enter fullscreen mode Exit fullscreen mode

This createUser function takes an user object and it will be posted in the gorest api. For the token you just need to signup in the gorest website.

Let's create a form page which takes name,email,gender and status which are the properties in the gorest api. I just handled the formData using useState here.

UserForm.js
import React, {  useState } from 'react'


function UserForm() {
   const [userData,setUserData ] = useState({
        name : '',
        email : '',
        gender : '',
        status : ''
    })

    const handleFormChange = (e) => {
        setUserData(
            {
                ...userData,
                [e.target.name] : e.target.value
            }
        );
    }

    const handleSubmit = (e) => {
        e.preventDefault();
        console.log(userData)

    }

  return (
    <div>
        <form onSubmit={handleSubmit}>
            <div className='field-container'>
            <label htmlFor='name'>Name : </label>
            <input type="text"  name='name' onChange={handleFormChange} value={userData.name}/>
            </div>

            <div className='field-container'>
            <label htmlFor='name'>Email : </label>
            <input type="email"  name='email' onChange={handleFormChange} value={userData.email}/>
            </div>



            <div className='fieldContainer'>
            <label htmlFor='gender'>Gender : </label>
            <input type="radio"  name='gender' onChange={handleFormChange} value='female'/> Female

            <input type="radio"  name='gender' onChange={handleFormChange} value='male'/> Male

            </div>

            <div className='field-container'>
            <label htmlFor='gender'>Status : </label>
            <input type="radio"  name='status' onChange={handleFormChange} value='active'/> Active

            <input type="radio"  name='status' onChange={handleFormChange} value='inactive'/> Inactive

            </div>
            <input type='submit' value={'Submit'} />

        </form>
    </div>
  )
}

export default UserForm
Enter fullscreen mode Exit fullscreen mode

On submitting this form I've just consoled the userData object. You can see the output in the following screenshot.

Image description

So for posting the data you need to trigger the function right. But how do we do that using useMutation.Let's see.

import { useMutation } from 'react-query'


const {mutate} = useMutation(createUser);

Enter fullscreen mode Exit fullscreen mode

This mutate is a function which should be triggered whenever you need and the data/payload you want to send should send as a parameter to this mutate function.

so my handleSubmit function would look like

const handleSubmit = (e) => {
    e.preventDefault();
    mutate(userData);

Enter fullscreen mode Exit fullscreen mode

As we handled in useQuery you can have isLoading for posting the data. With all the modifications, I just showed the response in my UI. lets see the code.

import React, {  useState } from 'react'
import { useMutation } from 'react-query'
import {createUser} from './userApi'

function UserForm() {
    const {mutate, isLoading} = useMutation(createUser, {
        onSuccess : (data) => {
            console.log(data) //This is the response you get back
            setResponse(data)
        }
    })
    const [response,setResponse] = useState({})
    const [userData,setUserData ] = useState({
        name : '',
        email : '',
        gender : '',
        status : ''
    })

    const handleFormChange = (e) => {
        setUserData(
            {
                ...userData,
                [e.target.name] : e.target.value
            }
        );
    }

    const handleSubmit = (e) => {
        e.preventDefault();
        mutate(userData)

    }

  return (
    <div>
        <form onSubmit={handleSubmit}>
            <div className='field-container'>
            <label htmlFor='name'>Name : </label>
            <input type="text"  name='name' onChange={handleFormChange} value={userData.name}/>
            </div>

            <div className='field-container'>
            <label htmlFor='name'>Email : </label>
            <input type="email"  name='email' onChange={handleFormChange} value={userData.email}/>
            </div>



            <div className='fieldContainer'>
            <label htmlFor='gender'>Gender : </label>
            <input type="radio"  name='gender' onChange={handleFormChange} value='female'/> Female

            <input type="radio"  name='gender' onChange={handleFormChange} value='male'/> Male

            </div>

            <div className='field-container'>
            <label htmlFor='gender'>Status : </label>
            <input type="radio"  name='status' onChange={handleFormChange} value='active'/> Active

            <input type="radio"  name='status' onChange={handleFormChange} value='inactive'/> Inactive

            </div>
            <input type='submit' value={'Submit'} />

        </form>
        {isLoading && <div>Posting the data...</div>}
        {Object.keys(response).length > 0 && (<div>
            <h4>Response</h4>
            <p>{response.name}</p>
            <p>{response.email}</p>
        </div>)}
    </div>
  )
}

export default UserForm
Enter fullscreen mode Exit fullscreen mode

The onSuccess method will be triggered once your post request is success and the data is the response returned after the post request.

The output I've generated in the following screenshot.

Image description

There would be some additional steps that need to be taken care of whenever you updating some values(making put request) and you want that change to be reflected back.But I want each of my post to be the essential so I'll just leave it to the next topic.Hope this is useful.

Top comments (0)