Follow Us:
How to Fetch data using React Hooks?
In this article, we’re going to talk about data fetching using React Hooks. React Hooks are features introduced in React 16.8 that lets you use state and other React features without writing a class.
But first, let’s talk about React Hooks.
Introduction to React Hooks:
React has always been about components. React Hooks are a way to reuse stateful logic, without having to re-render the component. Hooks let you split one component into smaller ones, each with its own isolated state.
There are two major benefits of using Hooks:
- You can use Hooks in any function component, not just in React class components.
- This lets you split stateful logic out of a component, so it can be tested independently and reused in other components.
Hooks let you reuse stateful logic without making a component wrapper.
In the past, if you wanted to reuse stateful logic, you had to make a higher-order component (HOC). A HOC is a component that renders another component.
React Hooks let you use that same stateful logic, without making a HOC. That means you can share Hooks among many components, without creating a HOC for each one.
Hooks are functions that let you “hook into” React state and lifecycle features from function components. Hooks don’t work inside classes — they let you use React without classes.
There are two types of Hooks:
- State Hooks: Let you use React state in a function component.
- Effect Hooks: Let you use React side effects in a function component.
React provides a few built-in Hooks like useState
. You can also create your own Hooks to reuse stateful logic across your application.
Creating a Custom Hook
You can create a Hook by defining a function starting with the word “use”.
Here’s an example:
function useCounter(initialCount) {
const [count, setCount] = useState(initialCount);
return [count, setCount];
}
This Hook is a function that takes an initial count and returns a count and setCount
pair. The setCount
function is used to update the count.
You can use this Hook just like a React state hook:
function Counter() {
const [count, setCount] = useCounter(0);
return (
<div>
<button onClick={() => setCount(count + 1)}>+</button>
<span>{count}</span>
<button onClick={() => setCount(count - 1)}>-</button>
</div>
);
}
This Counter component renders a + button, a number, and a – button. When you click the + or – button, the setCount
function is called, which updates the count.
You can also create a custom Hook to reuse other Hooks. For example, you could use a useCounter
Hook to create a useToggle
Hook:
function useToggle(initialValue) {
const [value, setValue] = useState(initialValue);
const toggle = () => setValue(!value);
return [value, toggle];
}
This Hook takes an initial value and returns a value and toggle function. The toggle function flips the value between true and false.
You can use this Hook like this:
function Toggle() {
const [isToggled, toggle] = useToggle(false);
return (
<div>
{isToggled ? 'On' : 'Off'}
<button onClick={toggle}>Toggle</button>
</div>
);
}
This Toggle component renders an On or Off state and a Toggle button. When you click the Toggle button, the toggle function is called, which flips the isToggled
value.
React hooks for Data fetching:
React provides a number of built-in hooks to make fetching data easier.
useState:
The useState hook is a built-in React hook that lets you use state in your functional components. The useState hook takes a single argument, which is the initial state. The useState hook returns a pair of values, the first value is the current state, and the second value is a function that lets you update the state.
useEffect:
The useEffect hook is a built-in React hook that lets you perform side effects in your functional components. The useEffect hook takes a single argument, which is a function. The useEffect hook is called after the component is rendered. The function passed to the useEffect hook is called the effect function. The effect function can return a cleanup function. The cleanup function is called when the component is unmounted.
useContext:
The useContext hook is a built-in React hook that lets you access the React context in your functional components. The useContext hook takes a single argument, which is the context object. The useContext hook returns the current context value.
useReducer:
The useReducer hook is a built-in React hook that lets you use a reducer function in your functional components. The useReducer hook takes two arguments, the first argument is the reducer function, and the second argument is the initial state. The useReducer hook returns a pair of values, the first value is the current state, and the second value is a dispatch function.
useCallback:
The useCallback hook is a built-in React hook that lets you memoize callback functions. The useCallback hook takes a single argument, which is the callback function. The useCallback hook returns a memoized callback function.
useMemo:
The useMemo hook is a built-in React hook that lets you memoize values. The useMemo hook takes two arguments, the first argument is a function that returns a value, and the second argument is an array of dependencies. The useMemo hook returns a memoized value.
useRef:
The useRef hook is a built-in React hook that lets you create a reference to a DOM element. The useRef hook takes a single argument, which is the initial value. The useRef hook returns a mutable ref object. The ref object has a .current property, which is the current value of the reference.
Now, let’s see how we can actually fetch the data using one of these react hooks.
Fetching data using an useEffect hook:
The first step is to install the Axios package.
To do this go to the project folder and open the terminal. Then write the following command-
npm install axios
Once the command completes installing the package it should be present in your package.json file.
Now we’ll create a new Component named FetchData.js. To do so, let’s create a file with that name and write the command “rfce“. The command rfce creates a React Functional Component with the ES7 module system.
Now let’s see the code here:
//Data fetching with useFetchData hook
import axios from "axios";
import React, { useState, useEffect } from "react";
function FetchData(){
const [data, setData] = useState([]);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState(null);
useEffect(() => {
const fetchData = async () => {
setIsLoading(true);
setError(null);
try {
const result = await axios("https://jsonplaceholder.typicode.com/posts");
setData(result.data);
} catch (error) {
setError(error);
}
setIsLoading(false);
};
fetchData();
}, []);
if (error) {
return <div>Something went wrong ...</div>;
}
if (isLoading) {
return <div>Loading ...</div>;
}
return (
<ul>
{data.map(item => (
<li key={item.id}>
<span>{item.title}</span>
</li>
))}
</ul>
);
}
export default FetchData;
// Explaination of the code-
// 1. We are using axios to fetch data from the API.
// 2. We are using useState hook to set the state of the data, isLoading and error.
// 3. We are using useEffect hook to fetch the data from the API.
// 4. We are using if-else condition to check if there is any error or data is loading.
// 5. We are using map function to display the data.
After completing this code, we’ll go to our App.js file and add this Component to that file.
import "./App.css";
import React from "react";
import {FetchData} from "./Components/FetchData";
function App() {
return (
<div className="App">
<h1>React App</h1>
<FetchData />
</div>
);
}
export default App;
So this is how using “useState and useEffect” hooks we can fetch data from a URL.
And this is our Output. You can see We’ve got all the titles according to their id inside an unordered list.
Now, we can do the same thing in our App.js file.
See the following Code:
import axios from 'axios';
import './App.css';
import React, { useState, useEffect } from 'react';
function App() {
const [data, setData] = useState([]);
useEffect(() => {
const fetchData = async () => {
const result = await axios(
'https://jsonplaceholder.typicode.com/posts',
);
setData(result.data);
};
fetchData();
}, []);
return (
<div>
<h1>Articles</h1>
<div className="articles-container">
{(
data.map((item) => (
<div className="item" key={item.id}>
<h3>{item.title}</h3>
</div>
))
)}
</div>
</div>
);
}
export default App;
Now, see both the codes are similar. Although it is a good practice to create a separate Hook component for fetching the Data.
And, as you might notice, ours App.js
is looking pretty clean; we managed to reduce the file length by a lot just by creating a reusable hook component. While working on a large-scale project these small things can be tremendously helpful for handling errors and also helps to increase the speed of the overall application.
There are many reasons why we should create a reusable hook component. One reason is that it can help reduce code duplication. If we have a react hook component that we can reuse, we don’t have to keep rewriting the same code over and over again. This can save us time and make our code more DRY (Don’t Repeat Yourself).
Another reason to create a reusable hook component is that it can make our code more modular and easier to maintain. If we have a large codebase, it can be difficult to keep track of all the different pieces of code. By creating reusable components, we can break our code down into smaller, more manageable pieces. This makes it easier to find and fix bugs, and make changes to our code in the future.
Finally, creating reusable components can make our code more readable and easier to understand. When we have a lot of code, it can be hard to follow the flow of execution. But if we have well-organized, reusable components, it can be much easier to see how our code works. This can be very helpful for other developers who are looking at our code for the first time.
Conclusion:
In this article, we’ve learnt about React hooks, how to create a custom hook and also we’ve learnt how to fetch data using a hook.
Hopefully, you’ve enjoyed reading and learned something new that will help improve your projects by encouraging you to build more modular components, reuse logic across the board and make it easier to test the logic.