useFetch
Overview
The useFetch hook is a custom React hook for handling asynchronous data fetching in a functional and reusable manner. It provides a Promise-based approach to manage fetching states and allows re-fetching data with updated inputs.
Importing
To use the useFetch hook, you need to import it:
import { useFetch } from 'jmaelementsreact/hooks/useFetch'
Type Definition
type Result<a,b> = [Promise<a>, (_:b) => Promise<a>]
The useFetch hook returns a tuple:
- The first element is a
Promise<a>representing the current fetching state. - The second element is a function that triggers the fetch with a new input of type
b.
Hook Signature
useFetch<a, b>(
fetch: (_: b) => Promise<a>,
input: b,
dependencies: React.DependencyList
): Result<a, b>
Parameters
- fetch: A function that takes an input of type
band returns aPromise<a>. This represents the asynchronous fetch logic. - input: The initial input of type
bused to call thefetchfunction. - dependencies: A dependency array (
React.DependencyList) that determines when to re-run the effect and refetch data.
Returns
A tuple of:
stateFetching: APromise<a>representing the current fetch operation.- A function to re-trigger the fetch with new input.
How It Works
- Initializes the fetching state (
stateFetching) with anullPromise(a placeholder promise). - Runs the
fetchfunction with the given input and updates the fetching state whenever dependencies change. - Provides a memoized tuple with the current fetching state and a function to trigger the fetch manually with updated input.
Example Usage
Here’s a practical example of using useFetch:
import React from 'react'
import { useFetch } from './path/to/useFetch'
// Example fetch function
const fetchData = async (id: number): Promise<string> => {
const response = await fetch(`https://jsonplaceholder.typicode.com/posts/${id}`)
if (!response.ok) {
throw new Error('Failed to fetch data')
}
return response.json()
}
const ExampleComponent = () => {
const [postId, setPostId] = React.useState(1)
// Use the custom hook
const [dataPromise, refetch] = useFetch(fetchData, postId, [postId])
// Handle the promise result
const [data, setData] = React.useState<string | null>(null)
const [error, setError] = React.useState<Error | null>(null)
React.useEffect(() => {
dataPromise
.then((result) => setData(result))
.catch((err) => setError(err))
}, [dataPromise])
return (
<div>
<h1>Fetch Example</h1>
{error && <p style={{ color: 'red' }}>{error.message}</p>}
{data ? <p>Data: {data}</p> : <p>Loading...</p>}
<button onClick={() => refetch(postId + 1)}>Fetch Next Post</button>
<button onClick={() => setPostId(postId + 1)}>Update Post ID</button>
</div>
)
}
export default ExampleComponent
Explanation
- Fetching Data: The
useFetchhook initializes thedataPromisewith the result offetchData. - Triggering Fetch: The
refetchfunction allows fetching new data with a different input value. - Displaying Data: The
dataPromiseis used to update thedatastate when resolved or handle errors when rejected.
Best Practices
- Dependency Management: Ensure that
dependenciesinclude all variables that should trigger a re-fetch. - Error Handling: Use
.catchor atry-catchblock to manage errors. - State Management: Consider managing the resolved data and errors separately for better UI feedback.
Notes
- The
nullPromiseplaceholder is used to initialize thestateFetchingto avoid null or undefined states. - The hook is optimized using
React.useMemoandReact.useEffectto minimize unnecessary renders and recomputations.
Contributing
If you encounter issues or have suggestions for improving the useFetch hook, feel free to contribute or report an issue on the repository.