Understanding React Hooks: A Practical Guide
When I first started working with React Hooks back in 2019, the whole concept felt oddly backwards. Why would we abandon class components that had served us so well? Three years and dozens of production apps later, I can tell you—Hooks changed everything about how we write React code.
Why Hooks Matter for Your Career
If you're applying for frontend roles at companies like Flipkart, Razorpay, or even startups in Bangalore's tech corridor, knowing Hooks isn't optional anymore. Every job posting mentions them, and interviewers will definitely test your understanding.
The useState Hook
Let's start with the most basic hook. Here's what most tutorials don't tell you:
const [count, setCount] = useState(0);
// Wrong way - this won't work as expected
const handleMultipleClicks = () => {
setCount(count + 1);
setCount(count + 1);
setCount(count + 1);
};
// Right way - use functional updates
const handleMultipleClicks = () => {
setCount(prev => prev + 1);
setCount(prev => prev + 1);
setCount(prev => prev + 1);
};
The functional update pattern is crucial when your next state depends on the previous one. I've seen senior developers miss this in interviews.
useEffect: The Tricky One
This hook trips up even experienced developers. Think of it as your component's lifecycle manager:
useEffect(() => {
// This runs after every render
document.title = `You clicked ${count} times`;
}, [count]); // Only re-run when count changes
Common Mistakes I've Seen
- Missing dependencies - ESLint will warn you, but many ignore it
- Infinite loops - Setting state inside useEffect without proper deps
- Memory leaks - Forgetting cleanup functions for subscriptions
Building Custom Hooks
Here's a practical hook I use in almost every project:
function useLocalStorage(key, initialValue) {
const [storedValue, setStoredValue] = useState(() => {
try {
const item = window.localStorage.getItem(key);
return item ? JSON.parse(item) : initialValue;
} catch (error) {
return initialValue;
}
});
const setValue = (value) => {
setStoredValue(value);
window.localStorage.setItem(key, JSON.stringify(value));
};
return [storedValue, setValue];
}
Performance Considerations
When working on apps with heavy traffic—think food delivery apps during lunch hours—performance matters. Use useMemo and useCallback strategically:
// Memoize expensive calculations
const sortedUsers = useMemo(() => {
return users.sort((a, b) => a.name.localeCompare(b.name));
}, [users]);
// Memoize callbacks passed to child components
const handleSubmit = useCallback((data) => {
submitForm(data);
}, [submitForm]);
What's Next?
Practice these patterns in a real project. Build a todo app, then a expense tracker, then something more complex. The muscle memory will develop naturally.
Hooks aren't just a React feature—they represent a shift in how we think about component logic. Master them, and you'll write cleaner, more maintainable code.