A connected component will re-render whenever there is a state change. While we want state changes to update our UI, we don’t necessarily want every state change to render every UI component. In this lesson, we’ll use the connect function to connect components to their own specific pieces of the state tree to make our rendering more efficient.
[00:00] Right now, we're using connect to wire up our Redux store with our top level app component. This means any time there's a change in our store, render is called an app which then renders all of the child components.
[00:11] If we look at the render method for app, all we're doing is taking the props passed in by our Redux provider and passing a subset of our state down to each one of these components. Todo list is getting the todos array, and todo form is getting the current todo along with a reference to the update current dispatcher function.
[00:30] Connecting my state provider at this top level works, but it's not very efficient. The problem here is that if I change the current todo, the only component that really needs to re-render based on that right now is the todo form.
[00:42] With this setup, my props are going to change at the app component level, so todo form will re-render, and we'll get our desired effect, but todo list is going to re-render with the todos that haven't changed at all.
[00:53] To demonstrate this, let's add some logging. I'm going to go to my todo form component. Right here at the top of my block, I'm just going to console.log, rendering form. I can save that. Then I can do the same for todo list.
[01:11] Here since I'm using the implicit return, I can just console.log my message which is just going to be list rendering, and then I can throw a double pipe in here. This or operator is going to see console log. It'll log out to the console, but console.log is also going to return an undefined.
[01:35] It'll see that undefined, and it'll evaluate whatever's to the right hand side of the or. If you're using stateless functional components where you use the implicit return, this is a nice way to debug.
[01:46] I'm going to save that. When the browser reloads, I'm just going to come over here and open up the dev tools. We'll see that we have rendering form and list rendering both logged out. That's from the initial load. That's going to happen any time the page is loaded because we need to render them out the first time. I'll clear that out.
[02:03] Now I'm just going to update my input. We'll see that I'm rendering the form, which I need to do because it needs to know about the input, but I'm also rendering the list which doesn't need to happen when this is the only piece of state that's changing.
[02:16] To make this more efficient, we're going to remove connect from our app component, and we're going to connect our individual to do form and to do list components giving them each the subset of the state that they actually care about.
[02:28] To do that, I'll start with todo list. I'm going to import connect from React Redux. Then I'm going to come down here to where I'm defining my component. I'm going to leave that console log in for now, and I'm going to remove this export default. Instead, I'm going to give this a name. We'll call it todo list. We'll set that to equal our function.
[02:54] Then down here, I'm going to add my export default back in. This is going to be a call to connect that returns a function that then will get our todo list as an argument. I'll break this off into multiple lines.
[03:09] The first argument for connect is our map state to props function. I'm going to accept state. In this case, I'm going to return an object that just has my todos. That's going to come from state.todos. I'll save that.
[03:30] Then I can go back into app.js. I can actually remove this prop from my todo list component, save it. It should still be loading up my initial todos. I'm going to come back into todo form. I'm going to do the same thing. I'm going to import connect from React Redux. I'm going to come down here. I'm going to take this export default.
[04:00] Instead, I'm going to give this a name, set it to equal our function. Then, down at the bottom, I'm going to export default with a call to connect, passing it the to do form component. I'm going to need my map state to props function again.
[04:21] In this case, I'm going to return an object that's going to have the current to do. That's going to come from state.current todo. I can save that. When the browser reloads, we'll see that we're rendering the form and the list because it's the initial load.
[04:38] Now, if I come up here to the input and I start to type, we'll notice that I render the form, but I don't render the list. I can do this as many times as I need to. All we're doing is re-rendering the component that actually cares about this piece of state. We've fixed our problem. We just need to clean up our code a little bit.
[04:56] I'm going to come back over to app.js. I'm going to take current to do out of to do form. We'll save that. Everything'll continue to work the way we expect it to. I have this change current. This isn't getting passed down yet. Let's fix that by coming up here.
[05:15] I'm going to take this update current import. I'm going to move that over to todo form. I'm going to update this path. Then I'm going to come down here to connect. I'm going to use the second argument of connect which is our map dispatch to props.
[05:32] I'm going to use the shorthand for this where I just pass in an object of keys and values that are dispatcher functions. I can save that. Now in props, I'm getting something called update current but before we were passing it in as change current.
[05:48] I'm going to update this to update current. Then I'm going to update the one reference I have to it to use update current as the name. We'll save that. Then I can come back into app.js. I can remove this. I can remove my reference to connect.
[06:06] Then down in the bottom of the file, all I need to do is export default app to export that top-level app component with no direct connection to Redux. I can come up into my render method. I can get rid of this change current prop that I'm passing in because the Redux connect function is going to take care of that for us. I can save that.
[06:31] Everything's still working. We can just verify in the browser that I'm rendering out my form when I change it. Now I just need to go into each of these components and just clear up these logs. In todo form, I'll get rid of this console.log. In todo list, I'll just take this log from the beginning of my return. Get rid of that. Save it.
[06:53] We'll just double check one more time that everything is working. My input's updating so I know everything's running as expected.