How to Build Custom React Hooks in TypeScript- useDebounce and useFetch
Here’s a step-by-step guide to creating custom React hooks in TypeScript based on the format you provided, including useDebounce and useFetch as examples.
1. How to Create Custom React Hooks in TypeScript
React Hooks allow you to reuse logic across multiple components. With TypeScript, you get type safety, making your hooks even more robust. The process of creating custom hooks in TypeScript is straightforward and follows the same principles as creating custom hooks in plain JavaScript.
2. What are React Hooks?
React Hooks were introduced in React 16.8 to allow function components to have state and side effects. Some built-in hooks include:
- useState – to manage state.
- useEffect – to handle side effects.
- useContext – to manage context.
Custom hooks are essentially functions that start with the word use and enable reusing stateful logic without repeating code across components.
3. Creating a Custom React Hook in TypeScript
Here’s a simple structure for a custom hook in TypeScript:
import { useState, useEffect } from 'react'; // Custom hook example in TypeScript function useCustomHook<T>(initialValue: T) { const [value, setValue] = useState<T>(initialValue); useEffect(() => { console.log("Value updated:", value); }, [value]); return [value, setValue] as const; } export default useCustomHook;
- The generic <T> ensures that the hook can handle different types of data.
4. Examples of Custom React Hooks in TypeScript
useDebounce Hook
The useDebounce hook delays the processing of user input until a specified delay period has passed.
import { useState, useEffect } from 'react'; // useDebounce custom hook function useDebounce<T>(value: T, delay: number): T { const [debouncedValue, setDebouncedValue] = useState<T>(value); useEffect(() => { const handler = setTimeout(() => { setDebouncedValue(value); }, delay); return () => { clearTimeout(handler); }; }, [value, delay]); return debouncedValue; } export default useDebounce;
- Parameters: value to be debounced, delay for the debounce duration.
- Usage: Helps in scenarios like search input to avoid unnecessary API calls on every keystroke.
Usage Example
const debouncedSearch = useDebounce(searchTerm, 500);
useFetch Hook
The useFetch hook is used to fetch data from an API, handling the asynchronous behavior and response.
import { useState, useEffect } from 'react'; // useFetch custom hook function useFetch<T>(url: string): { data: T | null, loading: boolean, error: string | null } { const [data, setData] = useState<T | null>(null); const [loading, setLoading] = useState<boolean>(true); const [error, setError] = useState<string | null>(null); useEffect(() => { const fetchData = async () => { try { const response = await fetch(url); if (!response.ok) { throw new Error('Error fetching 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;
- Parameters: url to fetch data from.
- Usage: To easily fetch data and manage loading/error states.
Usage Example
const { data, loading, error } = useFetch<User[]>('https://api.example.com/users');
5. Conclusion
Custom React hooks in TypeScript allow you to create reusable logic while leveraging TypeScript’s static type checking. Hooks like useDebounce and useFetch demonstrate the flexibility and power of hooks in handling stateful logic or side effects efficiently.
By using custom hooks, you can abstract away common logic and keep your components cleaner and more maintainable, all while enjoying the benefits of TypeScript’s type safety.