useMemo helps reduce heavy computation in functional components
useMemo
is similar to React.memo
but it helps to memoize the value instead of memoizing the component.
You can see how to use React.memo
in my previous article React.memo helps you to avoid re-rendering of computationally heavy components.
useMemo
is a hook that helps to memoize the value. It accepts a function that returns the value to be memoized and an array of dependencies. It will re-compute the value only when the dependencies are changed.
Let's continue with same example from previous article. We will use useMemo
to memoize the average rating of the book.
// BookList.js
const BookList = ({ items }) => (
<ul>
{items.map((item) => (
<BookItem key={item.id} item={item} />
))}
</ul>
)
// BookItem.js
const BookItem = ({ item }) => {
const [details, setDetails] = useState(null)
useEffect(() => {
fetch(`/api/books/${item.id}`)
.then((res) => res.json())
.then((data) => setDetails(data))
}, [item.id])
// Compute the average rating of the book
const averageRating = useMemo(() => {
if (!details) return null
return (
details.reviews.reduce((acc, review) => acc + review.rating, 0) /
details.reviews.length
)
}, [details])
return (
<li>
<h3>{item.name}</h3>
<p>{item.author}</p>
<p>Average Rating: {averageRating}</p>
</li>
)
}
export default BookItem
Why do we need to memoize the average rating of the book in this example?
The average rating of the book is computed from the reviews of the book. The reviews of the book are fetched from the server. The reviews of the book are not updated frequently. The average rating of the book is computed every time the component is re-rendered. It is not necessary to compute the average rating of the book every time the component is re-rendered. We can memoize the average rating of the book to avoid re-computing the average rating of the book every time the component is re-rendered.
How does useMemo work?
useMemo
accepts a function that returns the value to be memoized and an array of dependencies. It will re-compute the value only when the dependencies are changed.
const averageRating = useMemo(() => {
if (!details) return null
return (
details.reviews.reduce((acc, review) => acc + review.rating, 0) /
details.reviews.length
)
}, [details])
In the above example, the average rating of the book is computed only when the details
are changed. The average rating of the book is not computed when the component is re-rendered.
Hope this helps to learn useMemo
and also the difference between useMemo
and React.memo
.
Keep learning and share your comments by tagging me on twitter @learnwithparam š