Search code examples
reactjsaxioswebpackerreact-query

What is the correct way to pass parameters to a React-query useQuery method that uses Axios


I am currently building a Ruby on Rails Webpacker application with a React front end. I am at the point where I would like to create all the quires I need to make calls to my Rails API. I was loosely following this tutorial https://www.youtube.com/watch?v=0bKc_ch6MZY (https://github.com/daryanka/react-query-tutorial/blob/master/src/containers/Post.js, https://github.com/daryanka/react-query-tutorial/blob/master/src/Queries.js), in order to write some axios based query functions that I could use with react-query. I had no problem with getting the queries to behave as expected when the url for the endpoint was a hard coded string. When I attempted to pass in a parameter to make dynamic urls I ran into the issue of not having access to said parameter; specifically the "prodId" parameter. I did however notice that the "prodId" was inside the "key" parameter array like so:

queryKey: Array(2)
0: "product"
1: "1"
length: 2
enter code here

I could just access it from there but that approach does seem a little off, I also did not find any examples or documentation that attempted to access a parameter from the query key array. I would like to know what it is I am doing incorrectly with regards to passing in parameters? Were there some syntax changes in react-query that I am not taking into account?

react-query@^3.17.2

webpacker (5.2.1)

axios@^0.21.1

//Product.js

import axios from "axios"
import { getProduct } from "../../queries/products"
import { useQuery } from "react-query"

const prodId= '1'
const { data } = useQuery(['product', prodId], getProduct)

//queries/products.js
import axios from 'axios'

export const getProduct = async (key, { prodId }) => {
    console.log(opid)
    const { data } = await axios.get(`/api/v1/products/${prodId}`)
    return data
}

Solution

  • The query function that you pass to react-query gets a queryContext injected, which is an object that consists of the queryKey (and some more information if you are using an infinite query). So yes, one correct way to access dependencies is through the queryKey:

    export const getProduct = async ({ queryKey }) => {
        const [_, prodId] = queryKey
        const { data } = await axios.get(`/api/v1/products/${prodId}`)
        return data
    }
    const { data } = useQuery(['product', prodId], getProduct)
    

    Another way is to use inline anonymous functions, which is well documented in the docs in: If your query function depends on a variable, include it in your query key

    export const getProduct = async (prodId) => {
        const { data } = await axios.get(`/api/v1/products/${prodId}`)
        return data
    }
    const { data } = useQuery(['product', prodId], () => getProduct(prodId))