React Custom Hooks Collection
Build reusable hooks: useDebounce, useFetch, useLocalStorage, useIntersectionObserver.
ReactHooksCustom HooksReusable
Overview
Build reusable hooks: useDebounce, useFetch, useLocalStorage, useIntersectionObserver.
Project Setup
bash
npx create-react-app react-09-react-custom-hooks-collection --template typescript
cd react-09-react-custom-hooks-collection
npm install hooks custom-hooks reusableComponent Architecture
tsx
import React, { useState, useCallback, useMemo } from 'react';
interface Item {
id: string;
title: string;
status: 'active' | 'completed' | 'archived';
createdAt: Date;
}
interface ReactProps {
initialItems?: Item[];
onUpdate?: (items: Item[]) => void;
}
export default function ReactManager({
initialItems = [],
onUpdate,
}: ReactProps) {
const [items, setItems] = useState<Item[]>(initialItems);
const [filter, setFilter] = useState<string>('all');
const filteredItems = useMemo(
() => filter === 'all' ? items : items.filter(i => i.status === filter),
[items, filter]
);
const addItem = useCallback((title: string) => {
const newItem: Item = {
id: crypto.randomUUID(),
title,
status: 'active',
createdAt: new Date(),
};
const updated = [...items, newItem];
setItems(updated);
onUpdate?.(updated);
}, [items, onUpdate]);
const updateStatus = useCallback((id: string, status: Item['status']) => {
const updated = items.map(item =>
item.id === id ? { ...item, status } : item
);
setItems(updated);
onUpdate?.(updated);
}, [items, onUpdate]);
return (
<div className="max-w-2xl mx-auto p-6">
<h2 className="text-2xl font-bold mb-4">React Custom Hooks Collection</h2>
<div className="flex gap-2 mb-6">
{['all', 'active', 'completed'].map(f => (
<button
key={f}
onClick={() => setFilter(f)}
className={\`px-4 py-2 rounded-lg \${
filter === f ? 'bg-indigo-600 text-white' : 'bg-gray-100'
}\`}
>
{f.charAt(0).toUpperCase() + f.slice(1)}
</button>
))}
</div>
<ul className="space-y-3">
{filteredItems.map(item => (
<li key={item.id} className="flex items-center justify-between p-4 bg-white rounded-lg shadow">
<span className={item.status === 'completed' ? 'line-through text-gray-400' : ''}>
{item.title}
</span>
<button
onClick={() => updateStatus(item.id, item.status === 'active' ? 'completed' : 'active')}
className="text-sm text-indigo-600 hover:text-indigo-800"
>
{item.status === 'active' ? 'Complete' : 'Reopen'}
</button>
</li>
))}
</ul>
<p className="mt-4 text-sm text-gray-500">
Showing {filteredItems.length} of {items.length} items
</p>
</div>
);
}Custom Hook
tsx
import { useState, useEffect } from 'react';
function useLocalStorage<T>(key: string, initialValue: T) {
const [value, setValue] = useState<T>(() => {
try {
const stored = localStorage.getItem(key);
return stored ? JSON.parse(stored) : initialValue;
} catch {
return initialValue;
}
});
useEffect(() => {
localStorage.setItem(key, JSON.stringify(value));
}, [key, value]);
return [value, setValue] as const;
}Key Features
- Built with React and TypeScript for type safety
- Uses \useMemo\ and \useCallback\ for performance optimization
- Responsive design with Tailwind CSS
- React, Hooks, Custom Hooks, Reusable integration
Related Projects
ReactFeb 7, 2025
React Accessibility Audit Toolkit
Build an a11y testing tool that scans components for WCAG violations and suggests fixes.
ReactAccessibilityWCAGTesting
Read more → Source
ReactFeb 3, 2025
React Error Boundary & Fallback UI
Implement error boundaries with fallback UIs, error reporting, and recovery strategies.
ReactError BoundaryFallbackUX
Read more → Source
ReactJan 30, 2025
React PDF Viewer Component
Build a PDF viewer with page navigation, zoom controls, and text search functionality.
ReactPDFViewerComponent
Read more → Source
Comments (0)
No comments yet. Be the first to comment!