React: leveraging custom hooks to extract reusable logic
Scenario: Fetching Data
Instead of repeatedly writing code for data fetching in every component, you can encapsulate that logic in a custom hook. This makes your code cleaner, reusable, and easy to maintain. Let’s walk through a simple example.
1. Create a Custom Hook for Data Fetching
import { useState, useEffect } from 'react';
// Custom hook to fetch data
function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error('Failed to fetch data');
}
const result = await response.json();
setData(result);
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
};
fetchData();
}, [url]);
return { data, loading, error };
}
export default useFetch;
2. Use This Hook in Your Components
Now, you can use useFetch
in any component to handle API data fetching:
import React from 'react';
import useFetch from './useFetch';
function UserList() {
const { data, loading, error } = useFetch('https://jsonplaceholder.typicode.com/users');
if (loading) return <p>Loading...</p>;
if (error) return <p>Error: {error}</p>;
return (
<ul>
{data.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
}
export default UserList;
Why This is Useful:
Separation of concerns: The logic for fetching data is separated from the component itself.
Reusability: You can use
useFetch
in multiple components without duplicating code.Clarity: Components focus on rendering UI, making them simpler to understand.
🔨🤖🔧 Pro Tip: Custom hooks can do much more than just fetching data! You can use them for handling form inputs, subscriptions, or even implementing debouncing logic!