Custom Hooks in React(Data Fetching)

Rishu Kumar
3 min readFeb 21, 2024

Hooks that we create ourself, so other people can use them are called custom hooks.

A custom hook is effectively a function but with the following properties —

  • Uses another hook internally (useState, useEffect, another custom hook)
  • Starts with use

A few good examples of this can be —

  • Data fetching hooks
  • Browser functionality related hooks — useOnlineStatus, useWindowSize, useMousePosition
  • Preformance/Timer based — useInterval, useDebounce
Photo by Lautaro Andreani on Unsplash

Data Fetching hooks

Data fetching hooks can be used to encapsulate all the logic to fetch the data from your backend.

For example, look at the following code-

import { useEffect, useState } from 'react'
import axios from 'axios'

function App() {
const [todos, setTodos] = useState([])

useEffect(() => {
axios.get("Backend URL that renders a list of todos")
.then(res => {
setTodos(res.data.todos);
})
}, [])

return (
<>
{todos.map(todo => <Track todo={todo} />)}
</>
)
}

function Track({ todo }) {
return <div>
{todo.title}
<br />
{todo.description}
</div>
}

export default App

From the above code, don’t you think our app component is doing a lot of task, and let us assume that we have many components in our application where we have to do the same stuff where we have to fetch data form the backend server. So, to comply with the property of DRY Principle we can use the custom hook where we are just fetching data from backend and whenever the same thing is required in any component, we can use it easily.

Step 1 — Converting the data fetching bit to a custom hook

import { useEffect, useState } from 'react'
import axios from 'axios'

function useTodos() {
const [todos, setTodos] = useState([])

useEffect(() => {
axios.get("Backend url to get todos")
.then(res => {
setTodos(res.data.todos);
})
}, [])

return todos;
}

function App() {
const todos = useTodos();

return (
<>
{todos.map(todo => <Track todo={todo} />)}
</>
)
}

function Track({ todo }) {
return <div>
{todo.title}
<br />
{todo.description}
</div>
}

export default App

Step 2 — Cleaning the hook to include a loading parameter

What if you want to show a loader when the data is not yet fetched from the backend?

import { useEffect, useState } from 'react'
import axios from 'axios'

function useTodos() {
const [loading, setLoading] = useState(true);
const [todos, setTodos] = useState([])

useEffect(() => {
axios.get("url to enter")
.then(res => {
setTodos(res.data.todos);
setLoading(false);
})
}, [])

return {
todos: todos,
loading: loading
};
}

function App() {
const { todos, loading } = useTodos();

if (loading) {
return <div>
Loading...
</div>
}

return (
<>
{todos.map(todo => <Track todo={todo} />)}
</>
)
}

function Track({ todo }) {
return <div>
{todo.title}
<br />
{todo.description}
</div>
}

export default App

Step 3 — Auto refreshing hook

What if you want to keep polling the backend every n seconds? n needs to be passed in as an input to the hook

import { useEffect, useState } from 'react'
import axios from 'axios'

function useTodos(n) {
const [todos, setTodos] = useState([])
const [loading, setLoading] = useState(true);

useEffect(() => {
const value = setInterval(() => {
axios.get("url to enter")
.then(res => {
setTodos(res.data.todos);
setLoading(false);
})
}, n * 1000)

axios.get("https://sum-server.100xdevs.com/todos")
.then(res => {
setTodos(res.data.todos);
setLoading(false);
})

return () => {
clearInterval(value)
}
}, [n])

return {todos, loading};
}

function App() {
const {todos, loading} = useTodos(10);

if (loading) {
return <div> loading... </div>
}

return (
<>
{todos.map(todo => <Track todo={todo} />)}
</>
)
}

function Track({ todo }) {
return <div>
{todo.title}
<br />
{todo.description}
</div>
}

export default App

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Rishu Kumar
Rishu Kumar

Written by Rishu Kumar

Exploring the digital realm, one line of code at a time.

No responses yet

Write a response