With this week’s release of React 16.8, Hooks were finally released into the wild. They allow us doing a lot of stuff that wasn’t possible until now. For example, loading data into the state of a functional component. But let’s have a closer look.
In a recent post, I wrote about loading data from a REST API into a React component by using the componentDidMount
lifecycle method. That was the only recommended way to load data when a certain component has finished mounting.
And because it was the only way, we had to rewrite a functional component to a class component a lot. All of that just because we needed a little state or a lifecycle method … but no longer:
Hooks to the Rescue
With React Hooks there is another way to get data into your app. Finally we can have stateful logic in functional components – which allows us to have functional components as “containers”. If we now want a component to load data at mount, we don’t need a class component anymore. At least not just because we need state or lifecycle. Two Hooks make that possible: useState
allows us to add state functionality to our component. and useEffect
gives us the possibility to perform so called side effects like fetching data asynchronously.
Here’s a very basic example of a component that loads and displays a list of users from a REST API. Similar to the example in my recent post:
import React, { useEffect, useState } from "react";
import axios from "axios";
export default function RestApiHooksComponent() {
const [data, setData] = useState([]);
useEffect(() => {
axios
.get("https://jsonplaceholder.typicode.com/users")
.then(result => setData(result.data));
}, []);
return (
<div>
<ul>
{data.map(item => (
<li key={item.username}>
{item.username}: {item.name}
</li>
))}
</ul>
</div>
);
}
The useState Hook
Now let’s have a look at what happens here:
const [data, setData] = useState([]);
useState
uses array destructuring to provide the current value of a state (we called it data
) and a function to set a new state value (setData
). The argument that we pass to useState
is the initial value for data
in the component’s state. You can imagine the state of the component is now looking like that:
{
data: []
}
So now we have a state in our component. But how do we get the data from our REST API into that field? That’s where we need useEffect
:
The useEffect Hook
useEffect(() => {
axios
.get("https://jsonplaceholder.typicode.com/users")
.then(result => setData(result.data));
}, []);
At each render, useEffect
executes the function we pass as the first argument. We don’t want to load the users each time the component re-renders, so we pass an empty array as second argument.
The second argument of useEffect
allows us to pass dependencies to the Hook. For example, a value in state or a filter string that we could pass to our API. Each time one of those dependencies changes, useEffect
will be executed again. Since we only want to fetch data once, we pass an empty array.
Inside the Promise that we get from axios
we then update the state of our component with the freshly fetched data.
Wrapping Up
We should not go and rewrite our whole codebase to use Hooks and get rid of all class components. But I think it’s a great tool to make our codebase a lot cleaner.
It is totally fine to use Hooks and class Components in your codebase. So the next time you have to fetch some data when mounting, think of using Hooks in a functional component.
Did you already try hooks? Tell me in the comments about your experiences!
Como puedo conectar un Api utilizando React, axios y cookies para establecer la conexión?
De casualidad tendrás algúna explicación con ello?
Suponiendo que cuento con el x-token.
Hi!
Could you please provide more details about what you want to achieve?
Cheers,
Andreas
I’m able to fetch a single round of results, but how do I go about adding to the results when the array is inside an object? Like this:
“const [data, setData] = useState({ results: [] });”. For example, if you wanted to add a “Load More” button? Before hooks, I could just use the setState with spread operators but now with hooks I’m a little confused on how to do achieve the same result.