React Performance: useCallback to Avoid Unnecessary Rerenders

I wasted 6 hours debugging why my React component was slow. The component had 50 lines of clean code. But it re-rendered 400 times instead of 10. The culprit? A function created inside render. Here's the bug: ```jsx // BUG: Re-renders 400 times unnecessarily function ProjectCard({ project, onLike }) { const handleLike = () => { onLike(project.id) } return ( <div> <h3>{project.name}</h3> <button onClick={handleLike}>Like</button> // NEW function every render </div> ) } ``` Every time ProjectCard renders: - New `handleLike` function created - Child components see it as "changed" - Child components re-render - 400 parent renders = 400 child re-renders The fix: ```jsx import { useCallback } from 'react' function ProjectCard({ project, onLike }) { // handleLike stays the same reference across renders const handleLike = useCallback(() => { onLike(project.id) }, [project.id, onLike]) // Only recreate if dependencies change return ( <div> <h3>{project.name}</h3> <button onClick={handleLike}>Like</button> // Same function instance </div> ) } ``` Now: - `handleLike` reference stays same - Child components don't re-render unnecessarily - 400 renders → 40 renders (10x improvement) **The Pattern I Use:** Rule of thumb for my TypeScript+React projects: - Function passed to child = use useCallback - Computed value passed to child = use useMemo - Everything else = let React handle it **Real example from my portfolio:** In SphereMeet, the user list component was re-rendering 200 times/sec: ```jsx // BEFORE (slow) <UserList users={users} onSelect={(user) => updateSelected(user)} // NEW FUNCTION EVERY RENDER /> // AFTER (fast) const handleUserSelect = useCallback( (user) => updateSelected(user), [] ) <UserList users={users} onSelect={handleUserSelect} /> ``` Performance: 200 re-renders/sec → 2 re-renders/sec (100x!) **When NOT to use useCallback:** ❌ Don't use if: - Function is simple (1 line) - Not passed to child components - Child uses React.memo anyway - Dependency array is longer than function useCallback adds overhead. Only use when necessary. **The Lesson:** Most React performance issues are from: 1. Functions created in render 2. Objects created in render 3. Arrays created in render Fix those three, and React is blazingly fast. Comment "CALLBACK" + like + follow I'll send: → useCallback vs useMemo decision tree → When to use React.memo (and when NOT to) → Profiling tools to find re-render culprits → My real project examples (SphereMeet, Portfolio) (Must be following)

To view or add a comment, sign in

Explore content categories