Common React Mistakes: useEffect - Part 1

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

This is excellent. Thank you for sharing

👍︎︎ 3 👤︎︎ u/Megamind79 📅︎︎ Apr 19 2021 🗫︎ replies

Good stuff! Subscribed

👍︎︎ 2 👤︎︎ u/simplesphere 📅︎︎ Apr 19 2021 🗫︎ replies
Captions
in this video we're going to take a look at some common mistakes that people make when they use react's use effect as well as use callback and use memo and those pesky little dependency arrays we're going to come up with a bunch of rules that you can live by that are going to make your life much much easier but before we get into that if you like this video be sure to hit that like button if you really like the video be sure to hit the subscribe button and subscribe to the channel ring that bell and you'll be notified anytime a new one of these videos comes out we've also got a discord channel you can jump on and that's got a great little interview channel that you can jump on and have a talk about any kind of interview questions really cool check it out and if you like all that be sure to buy me a coffee without further ado let's jump into the office and get use effect use callback use memo and those dependency rays all figured out all right welcome to the new office and we're going to start looking at some viewer code here so this is an interesting little component and it's got some problems so the intent of this component is that we're going to have an array of numbers and then we're going to fetch those numbers from a json payload so let's go take a look at that it's got 123 in it and then we're going to go and display those numbers so let's take a look and see if that actually works and right now it gives us back an empty array and so there's basically three problems here the first is that they're using state in react in an odd way right they're basically going and setting the value as opposed to using the value setter and then the second is that they're using fetch right in the middle of a component definition which means that every time this component is going to be rendered it's actually going to rerun fetch and then the third is that there's i think an assumption here that this is sequential right we set the numbers we go and get the fetch the fetch completes and then we render it and that's just not the way that asynchronous code works so let's go put in a few console logs here and start seeing if we can figure out what some of the behavior is and learn from that the mechanics of basic state management in react but also use effect and dependency arrays and also use callback and eventually use memo and just kind of get a sense of a solid underpinning of how all this sort of stuff works so let's start off with a console log here we'll say that this is the start of my component and then we'll output the state so that'll tell us what the current value of state is and then we'll say that we are starting to render so let's go and just copy that one from the top and finally we'll capture the output here as a variable and then return it so we can put a little console at the bottom there on the way out and that'll tell us when we're done okay let's go over here to our inspector and we can see yeah okay so we get a started we get the numbers well in this case let's go and make that number zero so we just see the numbers which starts off as an empty array and then we get the render and then we get the finished but what's happening here is that fetch here is asynchronous so the control flow is like this it goes here it starts the fetch and then it renders and then it goes out and that's why it starts with an empty array and you don't actually get one two three by the time this gets done if you don't believe me let's go take a look here let's go and make this a function that has a body in it so i'm going to output the data coming back and also that we're finished our request and clear this out and run it again and you can see now the entire component rendering is finished by the time that we get the result back from that json fetch right so that's why we're not getting one two three in here if it was sequential then we'd have something along the lines of well we could just go and set this to you know four five six like that and yeah okay so we know that we're looking at the right data but we're not actually setting it properly so i think the first thing we want to fix is the the setting so i want to go back to a more conventional use of use date and that means to use break out this array like this and then do set numbers in there now this is how you state works right it gives us back the current value and that's a a constant right you shouldn't never change this and then it gives you back a setter and what the setter does is when you set the new value it immediately tells react to go out and re-render the component so what's our first big learning here when we get to this we go make a bunch of rules rule number one is to always use the setter for use date all right so we always want to use this we never want to set that value directly so let's go and change it out so now we're long no longer using the zeroth item there and instead we're going to do set numbers and this is quickly going to roll into our our second problem that we have which is that we're not using use effect and we've got fetch right in there as part of the render method essentially of this component so we'll hit save and immediately my browser is going to have start having issues you can see down here it's just continuously running and running and running and running right so why is that happening well so what's happening is the render starts and then during that we call that fetch that fetch then sets the numbers and that forces a re-render right so we're getting the right data yay yay okay something of a fix but now we're just continuously calling that json over and over and over again in fact it's it's overwhelming my machine the point where chrome is no longer really working if i go down here and inspect let's see if i can even get up the inspector i guess i can but yeah okay so there you go you're starting to see just just tons and tons and tons it's basically an infinite loop of fetches so how are we going to fix this well there's really two hooks within which you should go and set state in your functional component there is use effect and there is use callback use effect is wrong you use when you want to change state based on either being loaded or unloaded or if some other piece of state changes and you want to subsequently set another piece of state and then there's use callback which you use when you have a user interaction like a click and then you want to set state based on that so in this case because we're looking for something where we are going to set state based on being loaded or unloaded we want to use use effect so let's go and bring that in now use effect takes a function and within that you put whatever your state setting function is so in this case that's the fetch and eventually it will go and set that state now i will we'll just use that right like that and now go back into here and we'll see if we've solved the problem yeah it's not even bringing up the inspector at this point so let's try it again all right now unfortunately it looks like we're getting exactly the same effect again and that's predictable because use effect in this case is being run every single time this component is rendered and the reason is that we've provided no dependency array so the dependency array is the the second argument here and it basically tells react when should i go and run this function here and if you don't provide anything then it gets run on every single render which is clearly not what we want so that's a common mistake so let's put that in there always put a dependency array on use effect for sure actually i'll just add that use callback and use memo they all have it at least has to be there now what goes in it well a lot of people make another common error here which is to say this fetch is setting numbers and therefore it depends on numbers and so they put in numbers in here and the result is unfortunately exactly the same thing so we're on we're trying to improve this but we're ending up in exactly the same infinite loop again and again and again and it's very very frustrating and the reason that this is happening is that regardless of what number is is we're still going in fetching numbers again so even if numbers is now set to something that we like we are still fetching so one way to fix this would be to say okay well if we start off with a count of zero which we know would be the initial state that's the only point at which we should then fetch and just drop that in an if statement like that and now let's see i'm probably going to start up another tab and yay finally yay this works so we start rendering our component we have an array set to nothing we then render it we finish in the meantime we've started that fetch that fetch comes back to the data it then re-renders based on that new data and finally does the request finish i think what's a little surprising here is that all that rendering happens when you set to do that set which i think is actually pretty cool and fast so another way to do this and i think it's a cleaner way to do this is to leave this dependency array blank and that's because we know that we only want to make this request on the initial render of the component we only want to do this once so what happens is use effect basically starts off with this dependency array being internally undefined and then it does a comparison to whatever you provide which is an empty array but then the next time around it compares it to that empty array again and says well there's no difference so you get run once and exactly only once so i'm still getting a little warning here and that's because at this point it's telling me well you still are looking at numbers.length well let's get rid of that save it and now there you go i think that's actually the cleanest version of this code all right so let's capture that as one more rule to run use effect or any of these others only once use an empty array in addition to that another good rule is to say don't depend on data you set now that's not a hard and fast rule as you saw with my comparison numbers.length yes you can do that but just you got to be really wary about that and make sure that you're doing it the right way okay now there's two more hooks that use this dependency array and it's worth jumping into those and seeing how they work as well so you can avoid any common pitfalls with those as well before we get in there let's go and remove a bunch of these console logs kind of clean this up a little bit so we can have a much more tourist piece of code all right looks pretty good so let's talk about how to go and handle setting state based on user interaction so let's go and create an add one button that goes and adds another element to this array and see how we do that now in videos in the past what i've done is create a function right here and then use like something like set numbers give it a new array with the current numbers and then maybe the length of the array plus one and i'll set that to the on click handler let's see all right that works pretty well so this in this example this is probably fine but if you're going to go and build your own react hooks or if you're going to go and send this add one callback down to any sub-components that kind of thing then it's actually really advantageous to use use callback so let's go bring that in and use callback works a lot like use effect the first parameter is a function and then the second parameter is a dependency array so for the moment we're just going to set that dependency array to nothing seemed to work with the use effect i wonder what it's going to do here so let's do save and then add one that's kind of interesting so why is that happening we started with one two three we did add one then we got one so what's happening here is kind of a combination of javascript closures and also the fact that this dependency array is set to nothing so what happens is the first time that my component gets rendered the array is an empty array and then we create this add one callback and it goes in here and it says okay i'm going to capture the state of numbers which is an empty array and when i do set numbers i'm going to take that empty array and then add you know this next one that is the numbers.length which is zero plus one so you get that one that's how you get the array with a single value of one so how do we fix this well what we can do is we can regenerate the add1 callback anytime numbers is changed and the way that we do that is we just add numbers to that dependency rate now anytime numbers takes a new value we will get a new version of add1 so we'll save that and now it works because the callback gets regenerated every time now that callback has a stored value of one two three four five six seven eight and i wanna hit one add one now it's adding one correctly to that so that that works another variant of this is if you don't wanna go and keep creating new versions of add one every time numbers changes you can use a a different variant on how to do set numbers so let me get rid of that for a second and set numbers in this case can take one of two different options it can either take a value like in this case a new array or it can take a function and that function gets given the current value is expected to return from that a new value so we could do current value or current numbers and then return a new array based on current numbers and so now this add one is good forever it takes any current state and mutates it let's try that out and it works just fine so there's two different variations on for use callback for you and two different ways to manage that dependency so the last one i want to look at is use memo so let's create a little thing here called sum we're going to sum up all the numbers and to do that we're going to reduce the array so say that number is not reduced and that takes a function that function takes an accumulator and a new value and we're just going to add the accumulator and the value and that will return a new value for the accumulator and we'll start the accumulator at 0 and that'll give us our sum so let's go and i'll put the sum there and away you go now just like with use callback this is actually probably fine in this case this is not a particularly expensive routine uh but if you had something that was expensive but synchronous you would use use memo and what use memo allows you to do is take that expensive process and say only run that when this state changes so let's try this out so again we're going to wrap this in a hook use memo and we'll use an empty dependency array and we'll see what happens so now we've got sum at zero okay so why is that well again we start off with an initial state of an empty array so it comes down here to use memo the for on the first render and it says great i'm only going to ever run this once and i'm going to do this this reducing thing right now it does it on the empty array the sum of an empty array is zero and away you go so now it's zero and it's gonna be zero forever so again the way that we fix this we say well this one depends on numbers so we got to put that in there and this leads us to our final rule which is always add all the state you read from to the dependency ray let's go see if it works hey perfect nice all right so there you go the three dependency based hooks and also some common mistakes around them and also some rules that will help you avoid those mistakes in the future well i hope you've learned a lot about dependency rays use effect use callback and use memo and you've gotten some cool rules to live by but if you've got some rules to live by i would love to hear them be sure to put them in the comments section down below of course in the meantime from me to you be happy be healthy and be safe
Info
Channel: Jack Herrington
Views: 10,054
Rating: undefined out of 5
Keywords: react js, react js tutorial, react mistakes useEffect, common react mistakes, common mistakes in react, common mistakes in reactjs, react useeffect mistakes, mistakes to avoid reactjs, mistakes to avoid react hooks, react hook useeffect mistakes, reactjs mistakes to avoid, avoid mistakes for react hooks, common mistakes to avoid for react hooks, react useeffect mistakes to avoid, avoid reactjs mistakes, mistakes in react hooks, mistakes in react, common react js mistakes
Id: lStfMBiWROQ
Channel Id: undefined
Length: 19min 57sec (1197 seconds)
Published: Wed Mar 31 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.