Containerization of State within Child React Components

Tyler Clark
InstructorTyler Clark
Share this video with your friends

Social Share Links

Send Tweet

The changing of state is the reason why components re-render. If you lift all of your state up into the parent container and pass it down to child components, any update to that state in the parent affects all other sibling components. Causing many useless re-renders. By simply moving the state into that child component, saves having to use React.Memo on all sibling components.

https://github.com/twclark0/react-performance

Instructor: [0:00] This main dashboard component here is a parent component, meaning that it has a lot of children components within it. Within a lot of these children components, there are additional children components within them, creating a possibly infinite nesting of components.

[0:18] Let's say that you're a developer working on the Dashboard page, and a couple of these children components, namely the StatCard and the NewsCard, they need some additional state to make them fully functional. You might go ahead and add in a couple of useState hooks, one specifically for the NewsCard, one for the StatCard. Then, you end up passing this down as a prop to the corresponding components.

[0:47] I'll pass both the state and the function to update their states to each components, so that's the NewsCard here. Copy it and paste it for the StatCard, just changing the verbiage here. Now that they get them, we can destructure them inside of the class. I'll say, state and update state. Then just somewhere inside of the JSX let's throw in a button that we can toggle between.

[1:11] This would just be a button that updates the state with the opposite of the state and changing the text for that. Then we'll do the same thing for a StatCard, bringing in state and update state. Then, paste this one just somewhere with the individual component.

[1:34] Last but not least, let's make sure that we can watch how many times these components are rendering by having these console.logs inside of the component body. Perfect. Now we head over here. You'll notice that there are four Stat cards rendered, because there's four of them right here. Then just one News card rendered here.

[1:53] Notice that as we change this state that lives only inside of the NewsCard, we're going to rerender all four of the above Stat cards. Same thing for the StatState changed. We're going to rerender the NewsCard, even though the state changes happening inside of this child component.

[2:13] What's happening here is all of the children component within the Dashboard component are going to be rerendered. Even though nothing deals with them specifically, unless it's the stat or the news card, by having the state up here at the parent level, you're going to cause a rerender to all of these children components, unnecessarily.

[2:33] To fix this, we could go and add React.memo() to all of the components that tells it to only rerender if the props change, though there's a much easier way of doing this.

[2:45] It's the idea of containerizing the state only where it needs to be. For the new state, let's pull this out of the Home component and then instead put it inside of the NewsCard. We just need to change the values that we're using here.

[3:00] We'll find the button and change this state here and here. Same with the update state. We'll set it to setNewState. We'll get rid of these two props. Same thing for the StatCard. Let's get it out of the parent component. Put it inside of the StatCard. Remove these two props.

[3:29] Then we'll update the names of both of these. Put that here and here and the setStatState function. Perfect. Now we got rid of the state inside of those parents. We've stopped passing it down through props. Actually, we do need to remove those two props from both components.

[3:52] If we go back to our app here, you'll notice that as we change the state, we're only causing the StatCard to be rerendered and the same thing with the NewsCard. This might seem obvious as well because, why would I have put that to begin with?

[4:08] You'll find yourself as you're working with a lot of state, with a lot of components, it might be easier to just put everything at the top and pass it down as props so you're not managing that state and individual components.

[4:19] However, what you're doing is you're causing a lot of rerenders that are just simply unnecessary, and those do add up. As your app scales and grows, you're going to see a performance hit. For as much as possible, try to keep state to where it's needed.

[4:33] Keep it into those smaller children components. If you can't avoid it though, then work on using React.memo().