
React Hooks Deep Dive
A field guide to writing cleaner React hooks and avoiding effect-heavy component design.
Start by Removing State You Do Not Need
A surprising number of hook problems come from storing values that could have been derived from props, route params, or server data. Extra state creates extra effects, and extra effects create synchronization problems.
Before writing a custom hook, it is worth asking whether the component is trying to coordinate too many responsibilities at once.
Effects Are for Synchronization
The most useful mental model for `useEffect` is not side effects in general. It is synchronization with something outside React: the DOM, a subscription, a timer, local storage, or a network source.
If an effect only exists to reshuffle local values, there is usually a simpler approach. Derived state, event handlers, or server rendering often remove the need entirely.
Custom Hooks Should Clarify Boundaries
A good custom hook makes a concept easier to reuse and reason about. A bad custom hook hides several unrelated behaviors behind one convenient name.
When I extract a hook, I try to keep its contract obvious: what data goes in, what behavior it owns, and what shape comes out. If those answers are fuzzy, the abstraction usually needs to shrink.
import { useState, useEffect } from 'react';function useWindowWidth() { const [width, setWidth] = useState(window.innerWidth); useEffect(() => { const handleResize = () => setWidth(window.innerWidth); window.addEventListener('resize', handleResize); return () => window.removeEventListener('resize', handleResize); }, []); return width;}