Skip to main content

Custom Hooks

In essence hooks are reusable functions.

When you have component logic that needs to be used by multiple components, we can extract that logic to a custom Hook. Custom Hooks start with "use". Example: useFetch.

Build a hook

In the following code, we are fetching data in our App component and displaying it.

import { useEffect, useState } from 'react'

const App = () => {

const [data, setData] = useState([])
const [isLoaded, setLoaded] = useState(false)

useEffect( () => {

fetch('https://api.dev-master.ninja/reactjs/slow/')
.then(response => response.json())
.then(result => {
resolve(result)
})
.catch(err => reject(err))

}, [])

const renderContent = () => {
return( isLoaded ? <h1>Loaded!</h1>
: <h2>Loading...</h2> )
}

return(
<div>
{ renderContent() }
</div>
)
}

export default App

The fetch logic may be needed in other components as well, so we will extract that into a custom Hook. Move the fetch logic to a new file to be used as a custom hook:

File: src/hooks/useFetch.ts

import { useState, useEffect } from "react";

const useFetch = (url) => {
const [data, setData] = useState(null)
const [isLoaded, setLoaded] = useState(null)

useEffect(() => {
fetch(url)
.then((res) => res.json())
.then((data) => {
setData(data)
setLoaded(true)
})
}, [url])

return [data, isLoaded]
}

export default useFetch;

And now implement it in App.js

File: src/App.tsx

import useFetch from './hooks/useFetch'

const App = () => {

const [data, isLoaded] = useFetch("https://api.dev-master.ninja/reactjs/slow/");

const renderContent = () => {
return( isLoaded ? <h1>Loaded!</h1>
: <h2>Loading...</h2> )
}
return(
<div>
{ renderContent() }
</div>
)
}

export default App