REACT MEMO vs USECALLBACK vs USEMEMO

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
what's up everybody welcome to coding with haim did you know the react offers a function called react.memo which is meant to help you optimize performance also did you know the react offers a hook called use callback which is meant to help you optimize performance and also did you know the react offers another hook called use memo which is meant to help you optimize performance are you confused i was too so let's clarify that in this video so let's first take a look at how react.memo works so take for example what we have here on screen right we have a component called app which is rendering this child component right over here child component is expecting this child number as a prop to get passed down what we have also is the fact that our local component the one this app component right over here actually has a function that when you click that function local number is going to change so in other words when you call increment local only this local number variable here is going to change child number won't actually change and so what i would like to do now is if i'm actually clicking on this button to change local number i would like to have it where the child component doesn't actually re-render but as it stands right now every single time i'm going to actually click on this increment local button right over here what's going to happen is child will actually render which we're going to see based on the fact that we have this console log right over here so let's actually demonstrate that in action all right so if i come here and i go if i go ahead and now i click on click to increment local as you can see here we're getting this console log here if i click it again we see that the local variable's changing the child number is not in fact changing so therefore the actual property that's being passed down to the child is not changing but despite that we still actually have a child component going through another render cycle as you can see based on the fact that we're getting another console log so let's fix that [Music] okay so what i've done here is i basically imported this function called memo from react and then down here on line 17 when i'm actually going to export my child component i'm going to first wrap it in memo and basically all memo does is it basically looks at the props that are kind of incoming into the component and it basically says i will only re-render you if any of the props that you are receiving is in fact changing so let's go ahead and see that now in action so we're going to come back to the app so previously when i clicked on uh click to increment local child component was re-rendering but as you can see now the local number is changing but since the child number is not in fact changing i can keep clicking this but the child component is not actually rendering so that's basically what memo actually does again very simply if you have any props that are kind of going down to a component and you only want the component to actually render if it's props are actually changing you can use memo to basically say only allow me to re-render if my incoming props are changing so long as my incoming props are now changing don't re-render me now let's actually go ahead and take a look at how use callback works so in order to understand how use callback works we first have to actually go ahead and break our memo so let me show you what i mean by that [Music] okay so basically what i've done now is i've effectively created a new function called change child number now change child number is basically going to be a function that will receive a number as an argument coming back from the child and then we're going to call the set child number uh state handler right over here and we're going to set up that new number right so basically now we actually go down to the child the child has its own button which when you click on this button it'll go ahead and call the change number uh function right over here we should then call up to the parent components uh change number function that's being passed on via props and now we're going to go ahead and just pass in math.random to kind of just change it to an a new number every single time okay so now what i want to show you is with this little change that i just did by passing down a function as a prop to the child component this component will now no longer be properly memorized and will render every single time effectively i have now broken all the sort of performance optimization that i've added in earlier when i was using memo okay so now that we actually come back to the app i'm only going to click on the actual button to increment the number that's locally inside of app and not inside a child now watch what happens i click on that and once again now we actually see that this console log here is still logging inside of the child component even though i've used memo effectively i've broken my memorization but this is where the used callback hook will now come in very handy but in order for us to actually understand what just happened let's talk about something known as referential equality [Music] so say for example i have a variable called x whose value is 10 and then i have another variable b whose value is 10. if i now in console.log if i now in line 4 do console.log x is equal equal to b if i run this code i'll see that i actually get the output of true because effectively what javascript is telling me now is that the value of x and the value of b are the same effectively here what we're actually doing is we're comparing values but what if i did the following [Music] now basically what i've done is i basically made it where the where x is now an object that has a key on it whose value is 10 and b is now also an object that has a key in it whose value is 10. so if i now go ahead and run this code if i now say constant or log tell me whether or not x is equal equal to b what would you expect the output to be let's run it and see what happens as it turns out now i'm actually getting false so even though these objects look to be exactly the same still if i try to compare one to the other one i'm actually getting false and the reason for that is because whenever we compare objects in javascript what we're actually doing is we're basically checking the referential equality basically we're trying to see whether or not both of these objects are sort of allocated in the same space in memory if i did this if i went ahead and said that b is equal to x if i now go ahead and say x is equal equal to b i will actually get true now the reason for the reason why i'm now getting true is not because but in both cases now they're both the same magic object that have the same key whose value is 10. the reason why i'm now actually getting true is because both of these variables both b and x are both pointing to the same spot in memory in other words what we're doing is we're basically doing referential equality you don't actually have a brand new object we have the same object but with a new variable to kind of point back to that same object in memory so now when you come back to our react code here when we're basically passing down this change child number function down as a prop to the child component basically in every single render what we're actually doing is we're creating an entirely brand new function and then what ends up happening is the memo the react.memo function that we basically wrapped our child's component around what it's trying to do to determine whether or not a new prop has been passed down is it's basically just trying to do referential equality in other words it's not interested in comparing values because comparing values can be a slightly more expensive operation it's trying to be as efficient as possible so it's only trying to check the reference to see if the objects are in the same place in memory and so what ends up happening is every single time we go through another render cycle we're ultimately creating a brand new object and so therefore we're actually breaking the referential equality so how do we fix that well as it turns out that's where used callback actually comes into play [Music] okay so basically what i've done is i'm effectively creating a new function called memoize callback so use callback as a hook that we get from react and what it actually does is the following basically it accepts two arguments and then returns a new function but basically the first argument is going to be the actual function that you kind of want to memoize so in other words here basically saying that i'm going to have a function that will accept a number as an argument and then i'm actually going to go ahead and call whatever function i want in this case i'm trying to memorize the child number function and then i'm going to take the number that we received and then pass it onwards to the actual child number function and then we have this dependency rate that basically says that just like with use effect we kind of have the dependency rate that we only want things to change of things within the dependency rate change in this case we basically never want this to change therefore we can just use an empty dependency array but the point here basically now is that throughout the lifecycle of this component memorywisecallback will always be the same function in memory we're never actually going to be creating a new function so even as we kind of go through other render cycles where previously we kept creating a new function for every render cycle which then ultimately broke the way that react memo worked now we're just going to keep using the same function over and over and over again of course with different values but the function will basically stay referentially the same and so now if i actually go ahead and pass memoize callback down to the child component and run this code at this point even if i'm actually going to go ahead and try to do click to increment local you can see that the local number changes but the actual console log of here doesn't actually happen but if i actually go ahead and try to click the child number to change now the child value changes but the and and then the console log actually shows up but as long as i'm only changing the local variable even though i'm technically still passing down a function but since now i'm not passing down a new function i'm continuously passing down the same function because i've used callback because i've effectively memoized my callback function therefore now the component will actually only render if the props are kind of coming down to it are actually changing so basically now react memo is once again working by the power of use callback finally let's actually talk about the use memo hook okay so let's for example assume that we have an array with the numbers 1 through 18. of course this is a very contrived example but this will at least allow us to illustrate how react or the used memo hook actually works and what its benefits are so let's imagine we have this really large array and on every single render we're basically trying to compute or we're trying to output what is the largest number given in an array okay and so what basically have here is we have this h1 that'll say give me the largest number it'll then on every render call this get largest number function and all get largest number really does is it does a math.max math.max on the array and this would presumably be a very expensive operation so we don't really want to make this happen in every single render but as it stands right now it is actually going to happen in every single render as i'm going to demonstrate right now if i now come to the app and if i go ahead and click on increment local every single time i click that or if i try to click the child component every single time you can basically see the i am working log is actually happening and this is because on every single render we once again are calling that same function and we're once again going through the recomputation to get the largest number within the array on every single render now of course this is wildly inefficient on a very expensive operation so let's go ahead and make this more efficient using the used memo hook [Music] okay so what i've done is i've imported use memo and now here i'm basically going to use the used member hook and what i'm going to do is i'm basically going to create a new value called the memoize value and so use memo will accept the function as an argument and basically it's going to say it's going to do the following it's going to basically say i'm going to cache the value that this function outputs until such time that the arguments that this function depends on actually changes so since what's going to happen here is the get largest number function depends on the array i'm going to pass this array that we now have on state as a dependency inside of the dependency array and so until such time that this array doesn't actually change what's gonna happen is get largest number will just get will just always give me back the memoized value in other words the last computed value that it actually has it's now when i actually come down here to my h1 where i'm outputting the largest number instead of actually calling the function directly inside of my jsx what i'm actually doing is i'm simply going to put the memoized value right over there and so just to kind of prove that this all works i've actually also added a button that when you click on the button we're basically going to change what the array is set to so right now the array is basically a number that kind of goes from the numbers 1 to 14. but when you actually go ahead and click on this button we're now going to make it be a new array that goes from 60 to 90. and so what's gonna happen is as long as the array basically stays the same no matter how many times the component actually goes and re-renders for various other reasons this function of get largest number will not be re-computing and we'll basically be able to see that by the fact that we're not actually getting this console long again but then once they go ahead and click this button to actually change the array now we are basically busting the cache so this function will have to go ahead and recompute it then we're actually going to see that this function will in fact run the one time as we're actually changing what the array is set let's actually see that in action all right so basically i just refreshed the browser and as you can see right over here we have the largest number it's basically 14 and if you look at the console logs you can see that the i'm working ran one time because it basically ran the first time before the value has actually been memoized and if i click on any one of these functions to go ahead and call this function to re-render again or in other words to cause the app component to render again you can see that these values are changing local it's changing the child number is changing but the largest number is still saying set to 14 and crucially we're not actually seeing any more working logs inside of our console lock to indicate that that function design is not actually going through the process of recomputing the value to find the largest number within the array but if i go ahead and do change array now you can see we get the number 90 and we are seeing that it is in fact working but now if i come back here and if i change any of the other values once again now it's back to being memoized to the new value of 90. well that does it for this video hope you enjoyed it i hope you found it useful if you did please drop a like subscribe and i'll see you in the next video
Info
Channel: Coding With Chaim
Views: 22,159
Rating: undefined out of 5
Keywords: coding with chaim, usecallback, usecallback vs usememo, usememo, react usecallback, react memo, chaim friedman, react usememo, use callback, usememo hook, react usecallback vs usememo, codingwithchaim, react use memo, calvin friedman, use memo
Id: uojLJFt9SzY
Channel Id: undefined
Length: 13min 18sec (798 seconds)
Published: Mon May 04 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.