DEV Community

Cover image for How to call React Query hooks conditionally!
Nithin K Joy
Nithin K Joy

Posted on

How to call React Query hooks conditionally!

Yes, You heard it right! We are only able to use React hooks directly inside a component. If you put hooks inside a conditional statement or a looping statement we will get error (Error: Invalid hook call.)

Problem

Let us try it by using react-query useMutation or useQuery hook inside conditional statement.

We need to use it conditionally when you use same form component for both adding and editing data.

const submit = async data => {
    if (action == "Add") {
      const mutation = useMutation({
        mutationFn: addCompany, //post
        onSuccess: () => {
          queryClient.invalidateQueries({ queryKey: ['companies'] })
        },
      })
      mutation.mutate(data);
    }

    if (action == "Edit") {
      const mutation = useMutation({
        mutationFn: editCompany, //put,
        onSuccess: () => {
          queryClient.invalidateQueries({ queryKey: ['companies'] })
        },
      })
      mutation.mutate(data);
    }
  };
Enter fullscreen mode Exit fullscreen mode

Above code will result in this error

Error image when hooks is called conditionally or inside loops

Solution

Create new custom hook inside hooks folder and return useMutation hook with required properties passed from the component where it is called.

Create custom hook

import {useMutation} from "@tanstack/react-query"

const useMutateHook = (properties) => {
    return useMutation(properties)
}

export default useMutateHook
Enter fullscreen mode Exit fullscreen mode

Create another file and write code for action=="Add"

Post request or mutation.mutate for post request

In the below code we are just returning Object with mutationFn, onError, onSuccess methods.

// This code should execute when user is in add mode

import APIClient from "../../services/api-client";

const apiClient = new APIClient("/companies");

const addCompany = () => {
  return {
    mutationFn: data => {
      return apiClient.post(data);
    },
    onError: (error, variables, context) => {
      //handle error
    },
    onSuccess: (data, variables, context) => {
      //handle success
    },
  };
};

export default addCompany;

Enter fullscreen mode Exit fullscreen mode

Look at below code incase you want to know what does api-client.js file contain

import axios from "axios";

export const axiosInstance = axios.create({
  baseURL: "http://localhost:3500/api",
});

class APIClient {
  endpoint

  constructor(endpoint) {
    this.endpoint = endpoint;
  }

  getAll = (queryString) => {
    return axiosInstance
      .get(this.endpoint+queryString)
      .then((res) => res.data);
  };

  get = () => {
    return axiosInstance
      .get(this.endpoint)
      .then((res) => res.data);
  };

  post = (body) => {
    return axiosInstance
      .post(this.endpoint,body)
      .then((res) => res.data);
  };

  put = (id,body) => {
    return axiosInstance
      .put(`${this.endpoint}/${id}`,body)
      .then((res) => res.data);
  };

  delete = (id) => {
    return axiosInstance
      .delete(`${this.endpoint}/${id}`)
      .then((res) => res.data);
  };
}

export default APIClient;
Enter fullscreen mode Exit fullscreen mode

Create another file and write code for action=="Edit"

Put request or mutation.mutate for put request

//This code should execute when user is in edit mode

import APIClient from "../../services/api-client";

const apiClient = new APIClient("/companies");

const editCompany = () => {
  return {
    mutationFn: data => {
      return apiClient.put(data._id, data);
    },
    onError: (error, variables, context) => {
      //handle error
    },
    onSuccess: (data, variables, context) => {
      //handle success
    },
  };
};

export default editCompany;

Enter fullscreen mode Exit fullscreen mode

Finally import custom useMutation hook, addCompany hook, editCompany hook and use it as per your needs.

const mutation = useMutateHook(action == "Add"? addCompany():editCompany());
Enter fullscreen mode Exit fullscreen mode

Use custom useMutate hook or useQuery hook conditionally

If you found this helpful, be sure to leave a 💖 on the post. Thank you!

Top comments (4)

Collapse
 
geethanjaliks profile image
Geethanjali

I'm not clear about useMutation hook? Why this is used..

Collapse
 
nithinkjoy profile image
Nithin K Joy

useMutation is used to update the data by using PUT or POST or PATCH etc.

Collapse
 
geethanjaliks profile image
Geethanjali

Okay Thanks✨

Thread Thread
 
nithinkjoy profile image
Nithin K Joy

You're welcome ✨