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