Correctly useQuery with variable

I’m looking for the right method to use useQuery with variables fetching from another request.
I’ve got a function to get the foodtruck of the logged user. And once foodtruck is defined, I want to call my Query.

import React, {useEffect, useState} from 'react'
import {useQuery, gql } from "@apollo/client";
import { getAxiosAPI } from '../../lib/api';

const gqlReservationsByFoodtruck = gql`
  query Reservations ($foodtruck: ID!) {
    reservations (  where: { foodtruck: $foodtruck }) {
    schedule {
      id
    }
  } 
}
`

const Query = ({foodtruck}) => {
    const { loading, error, data } = useQuery (gqlReservationsByFoodtruck, 
        { variables:  {foodtruck:foodtruck && foodtruck.id} }
    );
    console.log(data, 'data')
  };


const parseVaiables = () => {

    const [foodtruck, setFoodtruck] = useState(null)
    
    //Get Foodtruck from User ID
    useEffect(() => {
        const getFoodtrucks = async () => {
            const response = await getAxiosAPI(`/foodtrucks?user.lastName=Borsti`);
            setFoodtruck(response.data[0])
        }       
    getFoodtrucks()
    
    }, [Query({foodtruck})])

  return (    
   <>                     
     
    </>
  )
}


export default parseVaiables

As you can see, I call my function Query in the input of my useEffect. It’s the only place when I didn’t get a infinite loop or a react queue error.

Also, like this, it’s working, but my Query function is still call with an empty variable foodtruck, so I get undefined data and a graphql error : "“message”:“Variable "$foodtruck" of non-null type "ID!" must not be null.”

What can I do to make it right ?

Thanks a lot !

Hi! The skip option is your friend:

const [foodtruck, setFoodtruck] = useState(null);
const { data, loading } = useQuery(gqlReservationsByFoodtruck, {
    variables: foodtruck?.id,
    skip: !foodtruck, 
});

useEffect(() => (
    (async () => {
        const response = await getAxiosAPI(`/foodtrucks?user.lastName=Borsti`);
        setFoodtruck(response.data[0]);
    })() 
), []);
1 Like

THANK YOU ! Not the first time and not the last time I miss an important feature :sweat_smile:

Can you told me why I cannot do:
foodtruck && Query(foodtruck) it gets me :
Error: Rendered more hooks than during the previous render.

Becaue, with skip, its doesn’t make any error message but it does render the function 5times…

That’s because react hooks have two rules that you must uphold:

  • Hooks must only be used in the root of react components or other hooks.
  • The number of hooks and their order must always be the same in each render.

If you make a hook conditional, that changes the number of hooks depending on if the condition is true or false.

Though I do wonder why your component would render five times. I would expect three renders:

  • The initial one on mount
  • The one after your axios request goes through and your state is set
  • The one after your graphql request goes through

Might be worth debugging, if just to gain an understanding of what’s happening under the hood.

1 Like