Last updated: Apr 7, 2024
Reading time·4 min

fetch in ReactTo fetch data on button click in React:
onClick prop on a button element.import {useState} from 'react'; const App = () => { const [data, setData] = useState({data: []}); const [isLoading, setIsLoading] = useState(false); const [err, setErr] = useState(''); const handleClick = async () => { setIsLoading(true); try { const response = await fetch('https://reqres.in/api/users', { method: 'GET', headers: { Accept: 'application/json', }, }); if (!response.ok) { throw new Error(`Error! status: ${response.status}`); } const result = await response.json(); console.log('result is: ', JSON.stringify(result, null, 4)); setData(result); } catch (err) { setErr(err.message); } finally { setIsLoading(false); } }; console.log(data); return ( <div> {err && <h2>{err}</h2>} <button onClick={handleClick}>Fetch data</button> {isLoading && <h2>Loading...</h2>} {data.data.map(person => { return ( <div key={person.id}> <h2>{person.email}</h2> <h2>{person.first_name}</h2> <h2>{person.last_name}</h2> <br /> </div> ); })} </div> ); }; export default App;

We set the onClick prop on a button element, so every time the button gets
clicked, the handleClick function gets invoked.
<button onClick={handleClick}>Fetch data</button>
We marked the handleClick function as async, so we are able to use the
await keyword to await Promises inside of it.
const handleClick = async () => { setIsLoading(true); try { const response = await fetch('https://reqres.in/api/users', { method: 'GET', headers: { Accept: 'application/json', }, }); if (!response.ok) { throw new Error(`Error! status: ${response.status}`); } const result = await response.json(); console.log('result is: ', JSON.stringify(result, null, 4)); setData(result); } catch (err) { setErr(err.message); } finally { setIsLoading(false); } };
handleClick function, we wait for the HTTP request to finish and update the state variables.At the start of the request, the isLoading state is set to true to show a
loading spinner if the request takes time.
We used the finally block to set the isLoading state back to false,
regardless if the request is successful or has failed.
finally { setIsLoading(false); }
If the request is successful, the data state variable gets set to the data
from the response, otherwise, the err state gets set.
On a successful response, the data gets rendered, otherwise, the error is
shown.
This example uses the native fetch API, but the concept applies if you're
using the axios package as well.
axios in ReactIf you decide to use axios, make sure you have the package installed by
running npm install axios.
# 👇️ If you use NPM npm install axios # 👇️ If you use YARN yarn add axios
Here is how you would fetch data on button click using the axios package.
import {useState} from 'react'; import axios from 'axios'; const App = () => { const [data, setData] = useState({data: []}); const [isLoading, setIsLoading] = useState(false); const [err, setErr] = useState(''); const handleClick = async () => { setIsLoading(true); try { const {data} = await axios.get('https://reqres.in/api/users', { headers: { Accept: 'application/json', }, }); console.log('data is: ', JSON.stringify(data, null, 4)); setData(data); } catch (err) { setErr(err.message); } finally { setIsLoading(false); } }; console.log(data); return ( <div> {err && <h2>{err}</h2>} <button onClick={handleClick}>Fetch data</button> {isLoading && <h2>Loading...</h2>} {data.data.map(person => { return ( <div key={person.id}> <h2>{person.email}</h2> <h2>{person.first_name}</h2> <h2>{person.last_name}</h2> <br /> </div> ); })} </div> ); }; export default App;

If you use axios, make sure you have the package installed by running
npm install axios in the root directory of your project.
The syntax when using the axios package is a bit cleaner and we have to deal
with less implementation details, but the concept is the same.
We have to set the onClick prop on a button element and make an HTTP request
every time the button is clicked.
<button onClick={handleClick}>Fetch data</button>
Every time the button is clicked, the handleClick function is invoked.
The first thing to do in the request handler is to set the isLoading state to
true to show a loading spinner if the request takes time.
const handleClick = async () => { setIsLoading(true); try { const {data} = await axios.get('https://reqres.in/api/users', { headers: { Accept: 'application/json', }, }); console.log('data is: ', JSON.stringify(data, null, 4)); setData(data); } catch (err) { setErr(err.message); } finally { setIsLoading(false); } };
The finally block takes care of setting the loading state back to false.
finally { setIsLoading(false); }
The finally block runs regardless if the request has succeeded or has failed.
If the request succeeds, we set the data state variable to the data from the
API.
setData(data);
If the request fails, we update the error state and render the error message.
catch (err) { setErr(err.message); }
If you need to wait for the state to update, click on the link and follow the instructions.
You can learn more about the related topics by checking out the following tutorials: