You only want to re-render components when the data for that component has changed. Often times you'll find that multiple instances of a component will re-render when the props change for one of them.
With React.memo
, you can now pass a stateless functional component to it and it will ensure that it does not rerender unless the props given to the component changes. In this lesson, you'll learn how to implement this with your stateless functional components.
NOTE: This does not work for Class based React Components, use PureComponent
or shouldComponentUpdate
.
Instructor: [00:00] Here we have a simple App component that has a form with a label for first name, an input. Then we have this Upper component that's simply rendering the children and calling toUppercase on it and also rendering a button that will keep track of how many times it's clicked.
[00:16] We have one for the first name. We also have one for the last name. When we render, we're going to console.log here. If I pop open my developer tools, I'm going to see we get rendering. We're also logging out the children prop.
[00:29] Then if we type something in here, like Tom, and then in here, Riddle, we're going to see a console.log for every time these Upper components are rendered. We have an Upper for first and an Upper for last. We'll get a console.log for each one of those.
[00:42] Let's take a look. First, we get that two rendering for rendering both of those. Then we get a rendering T and then a rendering nothing. That's for this last name.
[00:51] Then we get a rendering O. When we type the O, we get nothing rendered here for the last name.
[00:56] We're rendering the last name component over and over again, but nothing is changing about that component. Its props aren't changing. What is returned is not changing.
[01:05] This is a bit of a contrived example, but if this Upper function were doing some sort of expensive computation or it was rendering a very large tree, then that render is an unnecessary re-render and could lead to a performance bottleneck.
[01:17] We're OK with the state that's inside of this Upper component. If I go ahead and -- we'll clear that out -- then I click on that button to increment the count, we're only going to see rendering Tom. We're not going to see rendering Riddle unless we set the state there.
[01:30] That's because when we set the count here, React is simply going to re-render this component by itself. That's OK, but how do we make sure that the Upper component itself is not going to re-render unless the last name changes here or the first name changes here?
[01:44] What we're going to do is, I'm going to make a variable called Upper. We'll assign that to React.memo of this function. Then we'll save that. We'll get a refresh.
[01:55] We get both of those rendering there. Then we say, "Tom," and then "Riddle." You'll see we're only rendering the Upper component when the props are actually changing.
[02:04] This continues to work with our state. It's only re-rendering Tom here. It's only re-rendering Riddle here, so we're all set with React.memo.
[02:12] Now, re-renders of our App will not re-render the Upper component unless the props we provide to the Upper component are changed. To do this, we simply created a variable with the same name as our function component and assigned it to React.memo and passed our function component to React.memo.
[02:29] An important thing to note here is that you cannot use React.memo on class components. For those, you should use shouldComponentUpdate or PureComponent.
It's part of a playlist: http://kcd.im/hooks-and-suspense
Thanks Kent, learning a lot from your work. Appreciate ya!
@Kent, couldn't this work as a cache? Is the advantage of react-cache
that it works with Suspense
?
They're different use cases entirely. You could use them together if you want though.
@Kent Right, I looked into it further and see that React.memo isn't memoizing per function call, it is memoizing per re-render
https://codesandbox.io/s/8nr4xqrwj8
Here you will see the Hello component rendered twice. Each time the function is actually called, the output is not cached; however, the function isn't called each time the App is re-rendered.
@Kent I am building a simple lyrics app. A user gets a list of artists, once you click on an artist, you get a list of lyrics for that artist, and a further click on the lyric, shows the actual lyric to read.
I have a question about performance. Say I have a massive list of 6000 artists, performance wise, it isn't wise to load a list of 6000 artists on that first page render, what is the best way of achieving a list where more artists are loaded as the user scrolls down?
So initially load like 15 artists, and then as the user scrolls down the page, more artists are loaded.
@Jwan Windowing might be the answer.
What happened to the codesandbox ?! :( I got "Not Found We could not find the sandbox you're looking for."
Try again Eric, it's showing up for me.
Jwan, for displaying those artists, I recommend using react-window.
What course is this from?