React memo for component optimization

Maya Patel Jan 2026
2 tabs
import { memo } from 'react'
import { Post } from '@/types'

interface PostListItemProps {
  post: Post
  onLike: (id: string) => void
  onDelete: (id: string) => void
}

// Memoize expensive list items
export const PostListItem = memo(function PostListItem({
  post,
  onLike,
  onDelete,
}: PostListItemProps) {
  console.log('Rendering PostListItem:', post.id)

  return (
    <div className="p-4 border rounded">
      <h3 className="font-bold">{post.title}</h3>
      <p className="text-gray-600">{post.excerpt}</p>

      <div className="flex gap-2 mt-2">
        <button onClick={() => onLike(post.id)}>
          Like ({post.likes_count})
        </button>
        <button onClick={() => onDelete(post.id)}>
          Delete
        </button>
      </div>
    </div>
  )
})

// Custom comparison function
export const PostListItemAdvanced = memo(
  PostListItem,
  (prevProps, nextProps) => {
    // Only re-render if these specific fields change
    return (
      prevProps.post.id === nextProps.post.id &&
      prevProps.post.title === nextProps.post.title &&
      prevProps.post.likes_count === nextProps.post.likes_count
    )
  }
)
2 files · typescript Explain with highlit

React.memo prevents unnecessary re-renders of components when props haven't changed. I wrap components in memo when they're expensive to render or receive the same props frequently. The component only re-renders if props differ via shallow comparison. For deep comparisons or specific props, I provide a custom comparison function as the second argument. Memo works best with primitive props or memoized objects/functions. Without useCallback and useMemo, parent re-renders pass new function/object references, breaking memoization. I avoid premature optimization—profile first, optimize hot paths. Memo adds complexity, so I use it surgically for components that measurably benefit.