In the majority of React apps, the UI needs to receive data from a server via an API. In this guide, I will show you how to use React hooks to pass API response data into your components.
Here's an example of a component that will display a list of users:
1import React from 'react';
2
3export default function App() {
4 const [users, usersSet] = React.useState([]);
5 return (
6 <div>
7 <ul>{users}</ul>
8 </div>
9 );
10}
Use the useState
hook to create variables that will hold the list of users and update the same list of users (with usersSet
). Now you need to fetch the users from a server and display them in the component. One way to do this is by using the useEffect
hook directly in the component.
The useEffect
hook should be used when some variable or property changes, and you need to update your component to reflect that change. A change could be an asynchronous request to an API or any other side effect. useEffect
takes two arguments: a callback function and an array of dependencies. The array of dependencies will consist of variables that will be watched by the useEffect
hook. When any of the dependencies change the code in the callback, the function will execute. If the dependency array is empty, the callback function will only execute once as the component mounts.
1React.useEffect(() => {
2 async function fetchUsers() {
3 ...
4 usersSet(response);
5 }
6
7 fetchUsers();
8}, []) // An empty array means the callback will only execute once
9
10
11React.useEffect(() => {
12 async function fetchUsers() {
13 ...
14 usersSet(response);
15 }
16
17 if (isLoggedIn) {
18 fetchUsers();
19 }
20}, [isLoggedIn]) // The callback will execute every time isLoggedIn changes.
To populate the component with a list of users, you will need to fetch them from an API. Use the reqres API for this task.
1export default function App() {
2 const [users, usersSet] = React.useState([]);
3
4 React.useEffect(() => {
5 async function fetchUsers() {
6 const fullResponse = await fetch('https://reqres.in/api/users');
7 const responseJson = await fullResponse.json();
8 usersSet(responseJson.data);
9 }
10
11 fetchUsers();
12 }, []);
13
14 return (
15 <div>
16 <ul>
17 {users.map((user) => (
18 <li key={user.id}>
19 <h3>
20 {user.first_name} {user.last_name}
21 </h3>
22 <p>{user.email}</p>
23 </li>
24 ))}
25 </ul>
26 </div>
27 );
28}
In the above example the fetchUsers
call will only happen once, since it isn't listing any variables in the dependency array. It's also displaying the user's first name, last name, and email in the component.
If you need to share this same fetchUser
functionality with other components, you can move the useEffect
code into a custom hook. Creating a custom hook is relatively simple. You need a function with the word use
in front of the name. For example:
1// usersHook.js
2
3const useUsers = () => {};
4
5export default useUsers;
Hooks only work in
functional components
. They will not work inside of aclass
component.
Now you can move the hooks logic out of the App
component and into the useUsers
hook.
1const useUsers = () => {
2 // 1
3 const [users, usersSet] = React.useState([]);
4
5 React.useEffect(() => {
6 async function fetchUsers() {
7 const fullResponse = await fetch('https://reqres.in/api/users');
8 const responseJson = await fullResponse.json();
9 usersSet(responseJson.data);
10 }
11
12 fetchUsers();
13 }, []);
14
15 // 2
16 return [users];
17};
useState
and useEffect
code just moved into the custom hook. This code will function just like it did when it was inside of the App
component.users
object is returned. It is NOT
a requirement to return an array. You can return an object return { users }
or just the users
object return users
. Returning an array might make it easier for other developers to spot a stateful object. The array is the structure of what is returned from a useState
hook where the object at index 0 is the data and the object at index 1 is an updater function. In your custom hook you can return data however you want.All that's left is updating the App
component to use the custom hook:
1import useUsers from './usersHook';
2
3export default function App() {
4 const [users] = useUsers();
5
6 return (
7 <div className='App'>
8 <ul>
9 {users.map((user) => (
10 <li key={user.id}>
11 <h3>
12 {user.first_name} {user.last_name}
13 </h3>
14 <p>{user.email}</p>
15 </li>
16 ))}
17 </ul>
18 </div>
19 );
20}
You've learned how to fetch data from a server and use React's built-in hooks to update your component. You also learned how to create a custom hook for reusing your fetch logic in other components. For more information about hooks, check out this guide.
Thanks for reading and good luck with your next project!