Making HTTP requests is something that we have to do often in our React code.
In this article, we’ll look at where we should make API calls in React components that are made with React hooks.
API Call on Mount Only
To make an API call when the component mounts only, we can use the useEffect
callback with an empty array as the 2nd argument.
For instance, we can write:
import { useEffect, useState } from "react";
export default function App() {
const [user, setUser] = useState({});
const getUser = async () => {
const results = await fetch("https://randomuser.me/api/");
const {
results: [result]
} = await results.json();
setUser(result);
};
useEffect(() => {
getUser();
}, []);
return <div className="App">{JSON.stringify(user)}</div>;
}
We have the user
state with the useState
hook and it’s set to an empty object.
Then we define the getUser
function that calls fetch
to make a GET request.
We call results.json()
method to get the JSON response.
And then we call setUser
function to set the response as the value of the user
state.
Then in the useEffect
hook, we call getUser
to make the request.
The empty array lets us run the useEffect
callback when App
mounts.
And then we show the value to the user.
API Call Whenever Some Prop or State Changes
To make an API call whenever some prop or state changes, we can write:
import { useEffect, useState } from "react";
export default function App() {
const [id, setId] = useState(1);
const [todo, setTodo] = useState({});
const getTodo = async () => {
const results = await fetch(
`https://jsonplaceholder.typicode.com/todos/${id}`
);
const data = await results.json();
setTodo(data);
};
useEffect(() => {
getTodo();
}, [id]);
return (
<div className="App">
<button onClick={() => setId((id) => id + 1)}>increment id</button>
<p>{JSON.stringify(todo)}</p>
</div>
);
}
We have the id
and todo
states.
We want to make the API call to get the data with the id
value.
To make the request, we call fetch
with the URL string with the id
.
Then we call setTodo
with the data
.
Then we call useEffect
with a callback to call the getTodo
function.
And we pass in the [id]
array into useEffect
.
Below that, we have a button to call setId
to change the id
value.
And we display the todo
value below that.
Now when we click the buttons, we show the latest response after making the request with the given id
.
To watch props and make requests when a prop’s value is updated, we can write:
import { useEffect, useState } from "react";
const Todo = ({ id }) => {
const [todo, setTodo] = useState({});
const getTodo = async () => {
const results = await fetch(
`https://jsonplaceholder.typicode.com/todos/${id}`
);
const data = await results.json();
setTodo(data);
};
useEffect(() => {
getTodo();
}, [id]);
return <p>{JSON.stringify(todo)}</p>;
};
export default function App() {
const [id, setId] = useState(1);
return (
<div className="App">
<button onClick={() => setId((id) => id + 1)}>increment id</button>
<Todo id={id} />
</div>
);
}
We have the Todo
component that takes the id
prop.
And the rest of the code is the same as the previous example.
Conclusion
We can make API calls within React components created with hooks with the useEffect
hook.