In some situations, we may not need to re-render a component every time.
For example, if a component depends on a number n
, and our n
doesn't change. Or, if the page footer is quite complicated, and we make it so that our page does not re-render it every time because it is the same every time, we can use useMemo()
.
As an example, we are simulating a page footer here, and to add to its "work", we calculate 69!
(69 factorial). The value was the maximum number that can be displayed on a simple calculator.
Demo: https://codesandbox.io/s/vigilant-newton-5ocvf?file=/src/App.js
We can try clicking on the button to add the count on the page. The UI is quite responsive.
To experiment, let's increase the factorial to 30000!
(30,000 factorial), and here is a demo:
https://codesandbox.io/s/priceless-platform-ifigu?file=/src/App.js
We can see that every time we click on the button, the update on the page is really slow. That's because the Footer
component (or any costly component) is being re-rendered every time our count
is updated.
(sidenote: it also feels much longer than the 0.36 seconds (as tested on a MacBook Air). This partly may be due to the Footer
component has a really wide width to accommodate the number, so the browser has to spend a lot of resource to render it. If we merely prints out the binary length of the number, it is quite faster: https://codesandbox.io/s/divine-https-i6chz?file=/src/App.js But to keep it as slow as possible, we will print out the whole number again in the example below.)
So we can use useMemo()
to memoize the component (memoizing what Footer
returns).
const myFooter = useMemo(() => <Footer n={30000} />, []);
Demo: https://codesandbox.io/s/brave-noyce-zby1w?file=/src/App.js
Here, we are saying this component doesn't not depend on anything, so we provide an empty array at the end of useMemo()
. If for any reason we depend on some value to render this component, we'd add it to this array. This is similar to how useEffect()
works for its dependency array.
So here, when we click on the button, the page updates close to instantly, without going through the steps of getting the result from the Footer
rendering.
Reference: https://reactjs.org/docs/hooks-reference.html#usememo (Official docs)
P.S. It is Sept 2023 right now, and I am using a MacBook Air M2. The original "slow" app is taking only 0.09 seconds to re-render, so the unresponsiveness cannot be felt as easily. To change that, I have changed it to 60000!
(60,000 factorial), and also display only the length of it, so that we are not testing the webpage needing a super wide area to display the number. The example is at:
https://codesandbox.io/s/priceless-platform-ifigu?file=/src/App.js
and the version using useMemo
:
https://codesandbox.io/s/cranky-kare-fgp48m?file=/src/App.js
Top comments (0)