Author avatar

Marques Woodson

Passing Server Data into React Components Using Hooks

Marques Woodson

  • May 13, 2020
  • 5 Min read
  • 3,246 Views
  • May 13, 2020
  • 5 Min read
  • 3,246 Views
Web Development
Front End Web Development. Client-side Framework
React

Introduction

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:

1
2
3
4
5
6
7
8
9
10
import React from 'react';

export default function App() {
  const [users, usersSet] = React.useState([]);
  return (
    <div>
      <ul>{users}</ul>
    </div>
  );
}
js

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.

useEffect Hook

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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
React.useEffect(() => {
  async function fetchUsers() {
    ...
    usersSet(response);
  }

  fetchUsers();
}, []) // An empty array means the callback will only execute once


React.useEffect(() => {
  async function fetchUsers() {
    ...
    usersSet(response);
  }

  if (isLoggedIn) {
    fetchUsers();
  }
}, [isLoggedIn]) // The callback will execute every time isLoggedIn changes.
js

Fetching Users from a Server

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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
export default function App() {
  const [users, usersSet] = React.useState([]);

  React.useEffect(() => {
    async function fetchUsers() {
      const fullResponse = await fetch('https://reqres.in/api/users');
      const responseJson = await fullResponse.json();
      usersSet(responseJson.data);
    }

    fetchUsers();
  }, []);

  return (
    <div>
      <ul>
        {users.map((user) => (
          <li key={user.id}>
            <h3>
              {user.first_name} {user.last_name}
            </h3>
            <p>{user.email}</p>
          </li>
        ))}
      </ul>
    </div>
  );
}
js

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.

Passing Users to Multiple Components

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
2
3
4
5
// usersHook.js

const useUsers = () => {};

export default useUsers;
js

Hooks only work in functional components. They will not work inside of a class component.

Now you can move the hooks logic out of the App component and into the useUsers hook.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const useUsers = () => {
  // 1
  const [users, usersSet] = React.useState([]);

  React.useEffect(() => {
    async function fetchUsers() {
      const fullResponse = await fetch('https://reqres.in/api/users');
      const responseJson = await fullResponse.json();
      usersSet(responseJson.data);
    }

    fetchUsers();
  }, []);

  // 2
  return [users];
};
js
  1. In this example, the 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.
  2. Here an array with the 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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import useUsers from './usersHook';

export default function App() {
  const [users] = useUsers();

  return (
    <div className='App'>
      <ul>
        {users.map((user) => (
          <li key={user.id}>
            <h3>
              {user.first_name} {user.last_name}
            </h3>
            <p>{user.email}</p>
          </li>
        ))}
      </ul>
    </div>
  );
}
js

Conclusion

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!

18