‫Let's now take a look at a few strategies
‫that we can use
‫in order to prevent wasted renders related
‫to the context API.
‫And for that, let's actually come back to our APP.js
‫which is the one where we already use our context.
‫So, notice how here we don't pass around any props anymore
‫and we use our custom hook that is coming from our context.
‫So, we no longer need this.
‫We also need this file, of course.
‫And now in the index
‫let's go back to importing app from the app file.
‫Okay, and now let's see what we can do here
‫to optimize this a little bit.
‫But before we go do that
‫it's actually very important to understand
‫that you only need to optimize your context
‫in case that three things are true at the same time.
‫So first of all, the state
‫in the context needs to change all the time.
‫Second, the context has many consumers
‫and third, and probably most importantly
‫the app is actually slow and laggy.
‫So only if all of these are true
‫it is time to optimize context.
‫Now, the actual optimization of your context
‫can be quite confusing
‫because it's gonna depend a lot
‫on how you build your application
‫and how you set up your context
‫and also, what exactly you pass into the context.
‫And so, I cannot give you a clear recipe here
‫but I will just try to show you a few different things here.
‫So first of all
‫remember that we are already doing that optimization
‫where we pass the children into the component.
‫So what we render here, are simply the children
‫that we pass in.
‫So, these components right here.
‫And so, remember from earlier
‫that this makes it so
‫that these children are not all automatically re-rendered
‫because they were already created
‫before they were actually passed
‫into this provider component.
‫So let's just see that in action here, once again.
‫So as a record now
‫let's type something.
‫Let's stop, and so, here we see again
‫that these two components and also with the footer
‫are not automatically re-rendered.
‫And so, this alone is already a good optimization technique.
‫So, if we just had, basically this right here
‫here in the APP.js.
‫So basically what we did earlier in V1.
‫So
‫let's see
‫yeah, so remember how earlier this is what we had.
‫So we had these children here directly inside
‫the post context provider
‫and then all of these children right here
‫would also automatically have been re-rendered
‫as we changed the state inside that context.
‫So we already have that optimization going on
‫but if for some reason you are not doing that
‫then you should memo all of the direct children
‫of that context.
‫So basically what we did earlier
‫which is to wrap this component
‫and the main and the footer all into a memo.
‫So memorizing those components
‫so that they don't automatically re-render
‫once we update the state in the context.
‫Okay?
‫So that's one of the guidelines that I can give you.
‫So doing either this technique with the children
‫or to memorize the direct descendants of the context.
‫Now next up, let's try to see what happens
‫when we update the state in the application
‫above our provider.
‫So for example, this one right here.
‫So this state lives in the app
‫but since this post provider is a children of that
‫it'll then also automatically re-render.
‫And so, let's see what happens then.
‫And for that, let's also turn on again this setting here.
‫So recording why each component rendered.
‫Then let's clean this.
‫Let's clean this, as well
‫and then let's just start recording.
‫And now what I'm gonna do again is to change the state
‫in a component that is above or custom provider component.
‫So let's see what happens.
‫And indeed, now all the components did re-render
‫however, they did re-render for a different reason
‫that we might think.
‫So of course, app itself was re-rendered
‫because the state changed
‫but then for example, this one here
‫so the main was re-rendered because the parent re-rendered.
‫So that makes a lot of sense, right?
‫The same here.
‫And then we would expect the same to also happen
‫in the list.
‫However, the list did actually re-render
‫because the context changed.
‫Well, that's strange, right?
‫Because this state right here with the dark mode
‫actually has nothing to do with context.
‫But still all the components that consume the context
‫did now re-render because of context.
‫So the same thing here
‫and the same thing in the archive, as well.
‫And just keep in mind that we are now working
‫with a different app where we no longer
‫have the archive memorized, remember?
‫So we memorized the archive earlier
‫but now we are back in the other APP.js file.
‫But anyway, we would've thought
‫that all of these components re-rendered
‫because their parent re-rendered
‫which is what makes sense for these two, for example
‫not because context changed.
‫So why does that appear here?
‫Well, the reason is that
‫this value right here is an object, right?
‫And this post provider is a child element
‫of the app component.
‫And so therefore, when the app component re-renders
‫then this post provider re-renders, as well
‫and therefore, this object will be recreated.
‫And so, if this object will be recreated
‫it means that the context value has changed
‫and therefore, all the components that consume that context
‫are going to be re-rendered.
‫All right, so that's the reason why here we see
‫that the context has changed
‫because actually it did change because this value here
‫so this object did update.
‫So, the solution for that is to memorize this object.
‫So let's create that out here.
‫So let's do value
‫and then use memo as we have learned earlier.
‫And then here we need our callback function.
‫And so, this is then going to return
‫this exact object right here.
‫Place that here, use the value here
‫and then our dependency array.
‫Now, as we save this, you will notice
‫that this will create a few additional problems.
‫So let's see.
‫And so indeed, we are now missing the search Query
‫and the searched posts
‫so basically, these outside variables
‫that we are using in here.
‫So, search posts
‫and search Query.
‫So, let's try that again now.
‫So, let's maybe reload, clear this.
‫Let's start recording
‫and stop that.
‫And so now let's take another look.
‫And so, well, let's actually
‫get back the setting here because I reloaded the page.
‫So let's do that again.
‫And so, let's see here.
‫So, this time actually we see
‫that all of these components did re-render
‫because their parent component has re-render.
‫So we didn't actually fix the wasted render itself
‫but we did fix the fact that this render was caused
‫by our context.
‫And so, if we were to memo now these components
‫for example, let's try out the main component
‫then none of these components should render anymore.
‫Now again, in this case
‫since we don't really have this app very slow
‫there is no need
‫really to memo this
‫but all this is more to show you.
‫Right?
‫So make sure that you, if you want to write this code
‫that you import the memo function.
‫So just like this
‫and then let's clean this and go again.
‫Let's close that.
‫And now indeed, none of these components
‫is re-rendered anymore.
‫While again, I will just go back here now
‫to placing that here.
‫And hopefully you're not bored
‫by all these explanations without writing a lot of code.
‫But this is actually a bit more theoretical than practical.
‫But anyway, let's now see again.
‫And now, we are back to these components right here
‫that consume the context to being re-rendered
‫simply because this object here was recreated.
‫So let's place that back
‫and with this it is a lot better.
‫All right?
‫Now actually, I was expecting
‫that React would ask me to also include these two functions
‫into the dependency array right here
‫because it seems to me that they are also dependencies
‫here of this object.
‫So in case you get that, then you need to add
‫handle add posts and this one to the dependency array.
‫But if you do that, then you also will need to wrap
‫these two into a used callback, because otherwise
‫on each re-render these functions here
‫will be recreated again, which will then in turn also
‫make this object to be recreated again.
‫Now right, but in this case, that didn't really happen.
‫Let me just see what happens if I do
‫handle add post here.
‫Yeah, so then I get that warning
‫that I was just telling you about
‫which is that this function makes the dependencies
‫of the use memo hook change on every render.
‫So move it inside that callback or wrap it
‫in its own use callback.
‫So this is pretty helpful here, actually.
‫But in this case, let's just remove this from here
‫since apparently it is not really necessary.
‫Okay, but anyway, now let's finally also check what happens
‫when we update the state that is actually part
‫of the context itself.
‫So let's clean this here.
‫And so one example of course, of that is right here.
‫So let's see.
‫And then of course, all the components
‫that consume this context are re-rendered.
‫So that's the list, the search posts and the header itself
‫and I think also the archive
‫but somehow it doesn't show up here.
‫So, here it is again in this ranked chart.
‫So here we always have all of them
‫and then we can see that also all of these were re-rendered
‫because context has changed.
‫Now, I'm showing you this
‫because if you have many, many components
‫that are subscribed to a context
‫so that read data from a context
‫it will become problematic
‫to have so many different variables
‫inside the context value.
‫Because as soon as you change one of these states
‫for example, the post or the search Query
‫then all of the components that read
‫at least one of these five values will get re-rendered.
‫And so, again, this is not ideal
‫and it's the reason why in the beginning I told you
‫that we usually create one context per state.
‫So we would have one post context
‫and one search Query context.
‫And so, in that situation, whenever we updated
‫for example, the search Query, then all the components
‫that consume the posts would not get re-rendered.
‫While in this case, all of them are
‫because it is enough for one value here to change
‫to re-render the entire thing.
‫Now, I'm not gonna do that right here, but again
‫you can basically create one context
‫for this part and one context for this.
‫And then, what some people do
‫is to even take it one step further.
‫So inside the search Query context
‫you could even create one context only for the search Query
‫and one only for the state, update or function.
‫Or if you're using a reducer
‫you could then create one context
‫for the state and one context for the dispatch function.
‫And again, I cannot really show you that here
‫in this example because it'll depend so much
‫on your own situation
‫so, on your own application that you're building.
‫So these were just a few general guidelines
‫that I hope will become useful for you in the future.