Programming

React-Query How to useQuery when button is clicked

27 September 2026 · 9 min read

React-Query How to useQuery when button is clicked

React-Query has revolutionized data fetching in React applications, offering a robust and efficient way to manage server state. While often used for automatically fetching data on component mount, a common requirement is to trigger data fetching with useQuery based on user interaction, such as a button click. Mastering how to useQuery when a button is clicked is crucial for building interactive and responsive user interfaces. This approach allows for more control over when data is requested, optimizing performance and enhancing the user experience. In this comprehensive guide, we will explore various techniques and best practices for implementing this pattern effectively, ensuring your React applications are both performant and user-friendly.

Understanding the Basics of React-Query and useQuery

React-Query is a powerful library that simplifies data fetching, caching, and state management in React applications. It eliminates much of the boilerplate code typically associated with asynchronous data fetching, providing a declarative and efficient way to interact with APIs. The useQuery hook is at the heart of React-Query, responsible for fetching data, caching it, and providing the component with the necessary loading, error, and data states. Understanding its core functionalities is vital before diving into button-triggered fetching.

The useQuery hook takes two primary arguments: a unique key for the query and a function that returns a promise, typically an API call. React-Query automatically handles caching, retries, and background updates, significantly reducing the complexity of data management. By default, useQuery will execute the query immediately upon component mount. However, for scenarios where you want to delay the query execution until a specific event, such as a button click, you need to leverage the enabled option and the refetch function, which we’ll explore in detail in the following sections. According to the React-Query documentation, efficient data caching can drastically improve the performance of your application, reducing unnecessary network requests. Learn more about React-Query.

React-Query offers several benefits over traditional data fetching methods. It automatically handles caching, which reduces the number of API calls and improves performance. It also provides automatic retries in case of network errors, ensuring that your application is resilient to temporary connectivity issues. Furthermore, React-Query offers excellent developer tools for inspecting and debugging your queries, making it easier to understand and optimize your data fetching logic. These features make React-Query an invaluable tool for any React developer working with asynchronous data.

Implementing Button-Triggered Data Fetching with useQuery

To implement button-triggered data fetching using useQuery, you primarily rely on the enabled option and the refetch function. The enabled option allows you to conditionally disable the query from running automatically on component mount. By setting enabled to false initially, you prevent the query from executing until a specific condition is met, such as a button click. The refetch function, returned by useQuery, provides a way to manually trigger the query execution when needed. Here’s how you can implement this:

  1. Initialize useQuery with enabled: false. This will prevent the query from running immediately.
  2. Create a button element in your React component.
  3. Attach an event handler to the button’s onClick event.
  4. Within the event handler, call the refetch function returned by useQuery.

Here’s an example:

javascript import { useQuery } from ‘react-query’; import { useState } from ‘react’; function MyComponent() { const [enabled, setEnabled] = useState(false); const { data, isLoading, error, refetch } = useQuery(‘myData’, async () => { const response = await fetch(’/api/data’); return response.json(); }, { enabled: enabled }); const handleClick = () => { setEnabled(true); refetch(); }; if (isLoading) return Loading…

; if (error) return Error: {error.message}

; return (

{data && ``` {JSON.stringify(data, null, 2)}


} </div> ); } In this example, the `useQuery` hook is initialized with `enabled: false`. The `handleClick` function sets `enabled` to true and calls `refetch`, triggering the data fetching process when the button is clicked. This pattern ensures that data is only fetched when the user explicitly requests it, improving performance and reducing unnecessary API calls. Remember to handle loading and error states appropriately to provide a smooth user experience. The [benefits of refetching](https://courthousezoological.com/n7sqp6kh?key=e6dd02bc5dbf461b97a9da08df84d31c) extend beyond initial loads.

Advanced Techniques and Considerations
--------------------------------------

While the basic implementation of button-triggered data fetching is straightforward, there are several advanced techniques and considerations to keep in mind for more complex scenarios. For instance, you might want to pass parameters to your query based on user input or other dynamic factors. In such cases, you can update the query key dynamically, triggering a new fetch with the updated parameters. Additionally, you might want to implement debouncing or throttling to prevent excessive API calls when the button is clicked rapidly.

Consider a scenario where you want to fetch data based on a search term entered by the user. You can store the search term in a state variable and update the query key whenever the search term changes. This will trigger a new fetch with the updated search term. Here’s an example:

 javascript import { useQuery } from 'react-query'; import { useState } from 'react'; function MyComponent() { const \[searchTerm, setSearchTerm\] = useState(''); const { data, isLoading, error, refetch } = useQuery(\['myData', searchTerm\], async () =&gt; { const response = await fetch(/api/data?search=${searchTerm}); return response.json(); }, { enabled: false }); const handleSearch = () =&gt; { refetch(); }; return ( <div> <input onchange="{(e)" type="text" value="{searchTerm}"></input> setSearchTerm(e.target.value)} /&gt; <button onclick="{handleSearch}">Search</button> {isLoading &amp;&amp; Loading...

} {error &amp;&amp; Error: {error.message}

} {data &amp;&amp; ```
{JSON.stringify(data, null, 2)}

}

); } In this example, the query key is an array containing the base key 'myData' and the searchTerm. Whenever the searchTerm changes, React-Query will automatically invalidate the cache and trigger a new fetch when refetch is called. This ensures that the data is always up-to-date with the latest search term. Remember to handle loading and error states appropriately to provide a smooth user experience. For implementing debouncing or throttling, you can use libraries like lodash or underscore. According to Kent C. Dodds, “Premature optimization is the root of all evil (or at least most of it) in programming.” Only optimize when you identify a performance bottleneck. Read more about optimization strategies.

Best Practices for Using React-Query with Button Clicks

When implementing button-triggered data fetching with React-Query, there are several best practices to follow to ensure optimal performance and a smooth user experience. These practices include:

  • Handle Loading and Error States: Always provide visual feedback to the user while the data is loading or if an error occurs. This can be achieved by displaying loading indicators or error messages.
  • Optimize Query Keys: Use meaningful and unique query keys that accurately reflect the data being fetched. This helps React-Query efficiently manage the cache and prevent unnecessary fetches.
  • Use Debouncing or Throttling: If the button is likely to be clicked rapidly, implement debouncing or throttling to prevent excessive API calls.

Another important best practice is to leverage React-Query’s caching capabilities effectively. By default, React-Query caches data for a certain period, which can significantly reduce the number of API calls and improve performance. You can customize the cache time using the cacheTime option. For example, if you want to cache data for 5 minutes, you can set cacheTime to 300000 milliseconds. Additionally, you can use the staleTime option to control how often React-Query checks for updates in the background. Setting an appropriate staleTime can help balance the need for up-to-date data with the desire to minimize API calls. In fact, a study by Google showed that reducing page load time by just 0.1 seconds can increase conversion rates by 8%. Read the Google case studies on website speed.

Featured Snippet: To effectively useQuery when a button is clicked, initialize the hook with enabled: false. This prevents automatic data fetching on component mount. Then, use the refetch function returned by useQuery within the button’s onClick event handler to manually trigger the data fetching process. This approach gives you complete control over when data is fetched, optimizing performance and improving the user experience.

Infographic here
FAQ: React-Query and Button Click Events ----------------------------------------
**Q: Why is my `useQuery` hook not fetching data when the button is clicked?**
A: Ensure that the `enabled` option is set to `false` initially and that you are calling the `refetch` function within the button's `onClick` event handler. Also, verify that your query key is unique and that your API endpoint is correct.
**Q: How can I pass parameters to my query when the button is clicked?**
A: You can update the query key dynamically based on user input or other factors. This will trigger a new fetch with the updated parameters. For example, you can include the search term in the query key array.
**Q: How can I prevent excessive API calls when the button is clicked rapidly?**
A: Implement debouncing or throttling using libraries like `lodash` or `underscore`. This will limit the number of API calls made within a certain time period.
**Q: Is it possible to show a loading indicator while the data is being fetched after the button click?**
A: Yes, the `useQuery` hook provides an `isLoading` state variable that you can use to display a loading indicator while the data is being fetched.
By following these best practices and addressing common questions, you can effectively use React-Query with button clicks to build responsive and performant React applications. Remember to always prioritize the user experience and optimize your data fetching logic for the specific needs of your application.

By understanding the principles of React-Query and applying the techniques outlined in this guide, you can confidently implement button-triggered data fetching in your React applications. This approach provides greater control over data fetching, improves performance, and enhances the user experience. Embrace these strategies and elevate your React development skills to create more dynamic and responsive applications. Consider exploring other React-Query features like mutations and query invalidation to further optimize your data management strategies. Happy coding!

Question & Answer :
I am new to this react-query library.

I know that when I want to fetch data, with this library I can do something like this:

const fetchData = async()=>{...} // it starts fetching data from backend with this line of code const {status, data, error} = useQuery(myKey, fetchData()); 

It works. But how to trigger the data fetching only when a button is clicked? , I know I probably could do something like <Button onPress={() => {useQuery(myKey, fetchData())}}/> , but how to manage the returned data and status…

According to the API Reference, you need to change the enabled option to false to disable a query from automatically running. Then you refetch manually.

// emulates a fetch (useQuery expects a Promise) const emulateFetch = _ => { return new Promise(resolve => { resolve([{ data: "ok" }]); }); }; const handleClick = () => { // manually refetch refetch(); }; const { data, refetch } = useQuery("my_key", emulateFetch, { refetchOnWindowFocus: false, enabled: false // disable this query from automatically running }); return ( <div> <button onClick={handleClick}>Click me</button> {JSON.stringify(data)} </div> ); 

Working sandbox here

Bonus: you can pass anything that returns a boolean to enabled. That way you could create Dependant/Serial queries.

// Get the user const { data: user } = useQuery(['user', email], getUserByEmail) // Then get the user's projects const { isIdle, data: projects } = useQuery( ['projects', user.id], getProjectsByUser, { // `user` would be `null` at first (falsy), // so the query will not execute until the user exists enabled: user, } )