Learn the React useEffect Hook in 24 minutes (for beginners)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
- Yo what is going on guys, welcome back to the channel. My name's Sonny and today I'm gonna teach you all about the useEffect Hook and why it has transformed the way that we use functional components and why you need to know it. ♪ I know ♪ ♪ how they love you now ♪ (exciting future bass music) So today's lesson is actually part of the huge React Basics 101 pack. So the React Basics 101 class is full of value and I have been able to do something incredible for you guys, and that is to actually release it for absolutely free. Now the only reason that is possible is thanks to the guys over at Skillshare. Skillshare is an online learning community where millions of people come together to take the next step in their creative journey. The thing I love about Skillshare is that there are no ads. They're always launching new premium classes and they also recommend really interesting classes so before you know it, I'm actually no longer watching TV or Netflix. All I do is watch Skillshare while I'm actually eating my food. Most classes are under 60 minutes so they should be able to fit any schedule, whether you're super busy or you've got a little bit more time on your hands. I've actually gone ahead and dropped the React Basics 101 entire class on Skillshare. The first 1000 people to use the link in the description are gonna get a free month worth of Premium Skillshare. And you're gonna be able to with that access the React Basics which I've uploaded. On top of that you're gonna get access to thousands and thousands of courses available on Skillshare's platform. I've actually been checking out a amazing video editing class at the moment by Ali Abdaal, where I was actually able to find out how I could use my iPad to add animated handwriting into my videos to level up my production value. And now I'm making the best use out of my iPad as well as leveling up my Final Cut production game. So this is just an example of the amazing value that I've got since I've signed up at Skillshare. And if you guys wanna go ahead and benefit from this just like I have, then go ahead and remember the first 1,000 people to go ahead and grab that link are gonna get a one free month of Skillshare Premium, which means that you can access my React Basics 101 class it's completely free. You have nothing to lose. And then after that you can go ahead and continue if you're enjoying what you see on Skillshare. If you enjoy the content that you're seeing then go ahead and smash the thumbs up button, hit the subscribe and the bell notification icon so that way you don't miss any of the future videos without further ado let's roll the React Basics 101 useEffect lesson. Let's do this Pap fam. Peace. Today we're gonna be talking about the useEffect Hook. Now what is the useEffect Hook and why is it so important? It's actually one of the core fundamentals when we're using React, we have to understand how to use a useEffect token. We have to know why it's so powerful and the different use cases of when we might need to use it. Now what does a useEffect do? A useEffect Hook simply allows us to perform side effects on a functional component. Now you might be wondering, that sounds pretty cool but I have no idea what it really means okay? Now in a class based component, you used to have special functions called lifecycle methods. Okay? So these were things like componentDidMount, componentDidUnmount, componentWillUpdate and so forth. What this meant was that whenever the component would sort of reach a lifecycle point for example, when it mounts, when it's about to render, when it's about to rerender, what happens before the rerender so when it Unmounts, what happens when it receives new props, all of these things you could tap into and execute a piece of code based on those lifecycle functions. Now previously, you couldn't do this in functional components and as we know, the whole code base is shifting to functional components, functional programming. So with that said, the guys over React introduced the useEffect Hook. Now the useEffect Hook literally replaces every single one of those lifecycle functions or methods I explained just a second ago. Now we're gonna explain all of the different use cases. We're gonna break it down. We're gonna make it super simple. Get ready, buckle up, get your coffee. Let's go and jump into the code without further ado. So what we're gonna be doing here is essentially showing you how we have the same components, so this is a functional component, this is a class based component that resembles the same app. And essentially what we have at the bottom is with a minor difference of an input field, we have a render block over here. So we have the useEffector Hook with the window width, for an example in just a sec. And over here we have the same example where we basically go ahead and show the window width but we simply have an input for demonstration, which I'm gonna show you in just a sec. Okay? So with that said guys what I'm gonna show you is previously in class based components this is how you would go ahead and tap into those lifecycle functions that I spoke about. Okay so we had functions like this right? componentDidMount, componentDidUpdate, componentWillUnmount. Now there were some additional lifecycle functions however these are three of the most used ones okay? The first one what does that resemble? It resembles when the component mounts okay? So it's a lifecycle function weld so that we can call a piece of code when the component mounts. For example in this case, we could just console log the app component loaded. Right now this is very important because imagine you wanted to request something from a database, you could do it at this point. Now we also wanna run another piece of code whenever the component updates. So this is where componentDidUpdate used to come in. However this would run whenever you would basically get a change in props. This became a bit tricky when you're using this lifecycle functions so the useEffect does simplify this and we're gonna go over that in just a sec. The final one I wanna talk about is the componentWillUnmount now componentWillUnmount is as it sounds before the components about to rerender it unmounts first right? So the lifecycle that you have to expect is that whenever the page loads, the component renders onto the page and then the user might interact with the page, which may trigger a rerender. But before the page basically repaints, think of it that way, it unmounts that component and then it puts it back on the page right? So it has to first mount the component onto the page. So that way we see it. Then it's gonna receive some kind of interaction or change and that's gonna cause it to unmount the component and then remount it again. And that's what we see as an update. So that's how we get this interactivity or dynamic behavior with React. So we can actually tap into the point that it unmounts with the componentWillUnmount function okay? So these are the three sort of crucial lifecycle functions that I want you to focus on. Now in functional components it's actually very simple right? So once you understand that the useEffect Hook, so this one right here, the useEffect Hook it essentially replaces every single lifecycle function that you may run into okay? So the question is not if it is capable of doing so, it is capable of doing so. If you have any sort of concerns and you think, "Hmm I could do this in a class based component "but I can't do it in a functional." Then believe me you can do it in a functional component. You can do everything inside of a functional component now with our handy friend the useEffect Hook okay? So let's go through a couple of different variations and what you would use them for and how they compare to the class based methods that we just spoke about okay? So we're gonna go ahead and remove our current drawings and first one is we have the useEffect for triggering on every render okay? So firstly let's understand how we write the useEffect. So firstly you're gonna have to import it from React. That's the first typical step. And then what you're gonna do is type in useEffect okay? Now useEffect takes them some arguments. The first argument is actually a function. Okay so it's an arrow function. And the second one is optional okay so you don't have to include the second one. And there are reasons for when you wanna include it and their reasons for when you don't wanna include it. And this changes the behavior or the point at which we're tapping into it. So the different lifecycle functions or points in the component cycle that I talked about earlier, this will change that behavior based on the second argument. So here we can pass in something called a dependency list, right? So it's a dependency array. And simply if we leave it blank it does a certain behavior. If we put in a variable it has a certain behavior. And if we leave it blank without any sort of option there, it has a different behavior. So I'm gonna run through all of those right now but this is essentially how we write it. So the first example that I wanna talk about is on every render okay? So if we don't include that second argument, for example like so, then what we're gonna do is I'm gonna make this a little bit simpler. Let's just go ahead and say console.log I re-rendered. Right so this will trigger off every single time, the component rerenders. So imagine we have an input field, you type in it, it's gonna cause a rerender. So this we'll go ahead and have that effect. So let's go ahead and go to a component. Let's just type some stuff inside of here. So I'm gonna go ahead and comment out my previous console logs so that we know that it's coming from this one. So let's go ahead and refresh and now we can see, I re-rendered and if I type in a bunch of times, you can see every single time I type or some kind of rendering happens, it goes ahead and reflects on the page okay? So this is what is happening here. Now this is how we go ahead and tack into that point in the component lifecycle. So this allows us to have this power on every single render. However, this could be quite expensive, we don't always need that. Sometimes we only need to go ahead and render something on the first mount. For example the componentDidMount method over here. Right the componentDidMount method over here, we need a way of replacing that and that is over here. So as you can see over here, this useEffect call, what is the difference between this one and this one? So this one you can see has the dependency array inside of it right? But it has nothing inside the dependency array. And what that tells the React is only run this on the first render right? So only run it when the component mounts and after that, if there is subsequent rerenders don't run that code. Right so it's only when the component mounts right? And it's only when the component mounts first time. Right so essentially this right here by including this empty array dependency list will go ahead and replace this componentDidMount okay? So let's go ahead and see that in action. So I'm gonna go ahead and say here console log, and we're gonna keep this one for every single re-render. And here I'm gonna say let's just say the component mounted. Okay? So now if we go ahead and come back and refresh, it says the component mounted, and obviously that triggers as a rerender as well. But look what happens guys, if I go ahead and type the I re-rendered should fire off the component mounted should not fire off. So let's go ahead and type in. Perfect. You guys see that? The I rendered gets fired up with but component mounted did exactly as we expected it. It did not fire off again. So that's perfect and what that will essentially allow us to do is go ahead and replace this lovely snippet over here called the componentDidMount. So we don't actually need this complexity anymore. Now the useEffect can do that right? So really, really nice stuff. Now let's move over to the second bit where we're gonna talk about the componentDidUpdate placement. Okay so the componentDidUpdate previously only got triggered if the props changed however, we might want a bit more granular sort of control over this aspect right? So what we can do is we can actually replace this with the useEffect, but this time we go ahead and we simply include a variable inside of the dependency array. Now this is a array, which means you can include one or as many variables as you want in there at any time any of those variables changes, it will trigger off this code. Now you can see what we can do is we can include props in here. We can also include the pieces of state. We can include anything that we wanna go ahead and trigger the rerender for this makes it essentially a lot clearer because before when we saw componentDidUpdate it wasn't always clear that our re-render was about to happen or not. So this makes it essentially very very clear in knowing when that piece of code is gonna get triggered. Now a rule of thumb is that imagine we did not go ahead and include the dependency however, here we wanna say the name changed right? So we only wanna trigger it this off. When the name changed. If I go ahead and save this and I open up my compiler, you're gonna actually see that it warns us because hang on, you have a dependency in here. Your code is dependent on the name variable but you haven't included the name as a dependency inside of that dependency array. So if you go ahead and check your compiler, it'll actually warn you of this it'll say "React Hook useEffect has a missing dependency name. "Either include it remove at the dependency array." Now if we remove it, it's gonna go ahead and trigger on every re-render, which isn't optimal. So we need to go ahead and Pap in the variable that it's dependent on so that I hope that makes sense. And imagine we had different ones. Imagine we have another variable called age for example, then you would also need to go ahead and include it here. So that way this code reflects the latest values as it's dependent on these two variables. Okay so whatever variables you use inside of here, whether it's props, pieces of state, they have to go inside of this right? Now if we go ahead and get rid of the age, because we didn't define a variable so it would error out. So let's go ahead and do that and you should see a green little compiled successfully message and that's perfect. Right? So with that said this one over here. So this over here is gonna be responsible for replacing the componentDidUpdate lifecycle method. And it works perfectly guys. It really, really does. And it makes your code base much simpler because you look at the useEffect and you know that this code is only gonna get fired off when the name variable changes. Now something to remember you can see here that it also runs on the first render. Okay so every single useEffect always fires on the first render right? So when the component mounts, this is just a rule of thumb. We must understand this. It always will fire at once when the component loads okay? So even if we go back here and you guys can read the React docs to make, to understand why that happens, but I can go ahead and refresh and you see the name changed right? And if as soon as I start typing in right? So in this input field at the bottom, I have an example where I'm just essentially changing the name of variable via a set name and re-mapping it to the name. So let's go ahead and change the name input. So here it says enter a name. So if I say Sonny, so as soon as I type in every single time I type in, it re-triggers that code. You see it says the name changed our rerender code, which was in the other useEffect gets triggered off. And also the one that we just explained now that will get fired off too right? So I hope that makes a lot of sense. And that is where we go ahead and essentially replace the componentDidUpdate lifecycle method. Now the final example, and this is probably the one that will, may take a few moments to get your head around is the componentWillUnmount lifecycle function okay? So how do we replace with a useEffect? Now the useEffect allows us to have something called a cleanup function okay? So in every single useEffect so let's use this one for an example, what we can do is we can actually return a function from the useEffector okay and what this will do is it's known as the cleanup function okay. Now what this means is before it essentially re-renders, so before imagine I'm typing into that input field, every single time I type in it rerenders right? But before it does that it actually quickly unmounts the component so that it can rerender another one in its place where we see it happen so quick that it looks dynamic in front of us. But what actually, what we can do here is we can actually go ahead and unmount something so in this case, let's go ahead and demonstrate before the name changes. Let's go ahead and say we unmounted. So let's go ahead and do this and save. And what we can do is, and this is actually very powerful because there are going to be cases where for example, you make a connection to a database and every single time the component rerenders you don't wanna keep making the connection. Instead you have to do a clean up, you have to disconnect the current connection and then reconnect or it would even be better to only do it on the first render. Right so this is where you have to think about these things, to know which useEffect or which implementation to use. But let's check this out in action okay. So I'm gonna go ahead and refresh and let's go ahead and say type in Sonny. So look what happens guys. It unmounted, it re-rendered and the name changed. And here if I go ahead and type in Sonny as such, you can see it happened a bunch of times. The name changed, we unmounted, I re-rendered, the name changed. And then if I go ahead and type in again, it went it said we unmounted it re-rendered and the name changed. Right so you see what happens here. It has to unmount first then it goes ahead and updates the name okay? So this is called the cleanup function. Now I've got a really cool example of how we can show you this one. So what we've done here is I've created a little helper function called const updateWindowWidth okay? Now bear with me for a sec. At the top we've initialized a variable inside of our state called window width okay? Now what we've done here is essentially set the initial value with the window in a width property okay? So this will actually just return a value, which tells us how wide the width of the screen is okay? And what we've done here is on the first render so obviously here what we're saying is on the first render, but I'm gonna show you something first. We're gonna say on every single rerender, I wanna add the event listener so that when the user resizes, I update the window width and this is a function, which simply goes ahead and sets the window width, to the new window in a width okay? So every single time it will do that. But let's not have a cleanup function and I'll show you what happens okay? So I'm gonna go ahead and comment this out for now or what we can actually do at this point is I'll cut this out and I'll show you the sort of implications if you do this without correctly cleaning up. So what we're gonna see now is this should actually reflect on the screen. But what we're gonna see now is if we go ahead and refresh you see here it says the window width is four six six So if I go ahead and move it around, you can see it's re-rendering and this is changing value. Okay? So I'll useEffect is working here. It's actually triggering off to update that window value. However, what we're not seeing here is that every single time it triggers that rerender, it's adding an event listener to the resize action with the updateWindowWidth function. Okay? So that's actually quite expensive, although we might not see any harm here and it works perfectly, what we can actually do is we can run a piece of code inside of our console called get event listeners for window inside of parentheses. And you can see you look it has 113 listeners. And if I go ahead and drag this around a few more times and I run it, it's gonna have another 146 because it re-rendered that three more times after that. Right and if we do it again you can see like I'm just gonna go crazy now. And then let's go ahead and do it again and we've got another 50 re-renders. So you can see now it's added another 50 resize listeners. This is not ideal, and it can extremely impact your performance of your React app okay? So I'm gonna go ahead and refresh and you can see just to prove to you that it starts off with one. We do this a bunch of times and you can see for example, 24 re-renders later we now have 26 inside of our resize listeners alright, which is not ideal. So there's two ways of fixing this. The first one is with a cleanup function. So let's go ahead and say okay, before you re-render, let's go ahead and return. So the cleanup function. So when the component mounts this clean up code will run. We're gonna say remove the event listener that you added with the updateWindowWidth function. So let's go ahead and do that alright? And let's just see what happens now. So if we refresh, we go ahead and see how many listeners have been attached. Okay remember because it runs the first time it mounts. So this is why it is able to work. And let's go ahead and do this a bunch of times. So let's go ahead and move this around so we can see, okay I've dragged it around a bunch of times. It says I re-rendered okay? Now let's go ahead and say, get the event listeners and you can see we only have one. Right? So this is again really, really nice. And it works really, really well okay? Now there are ways, there are things to consider with this right? Every single time we do this, it's gonna go ahead and let's just say console.log and let's just say attach listener. Okay? We're gonna attach the listener at this point. And I'm gonna go ahead and copy this. And here I'm gonna say detach listener right? So you can see, you might be thinking problem solved right? But look what is actually happening here okay? So we attached to the listener and then here, if we go ahead and check it, it attach that listener right? Perfect. And if I go ahead and re-size the screen, you can see what's happening right? Every single time I do it, although we only have one resize listener available, which is what we wanted. It's actually doing quite a lot of work behind the scenes that we don't even notice right? It's attaching, rettaching, attaching, detaching, attaching and so forth so this is not ideal. So what you can do is in this sort of situation to further optimize your React app you can go ahead delete this go ahead and actually only run this on the mount right? So remember it depends on your use case but in this case this would actually work perfectly because we only wanna attach the event listener once when the component mounts. And then we wanna basically go ahead and just carry on with our day. Right so let's go ahead and save this. And now if I go ahead and check it, refresh it attached to listener. We can see it's only got one resize array and then we can go ahead and do this. And now regardless of the number of rerenders you can see, our functionality is perfect, but we don't have any additional resize listeners nor is it attaching and detaching every time. It only attached once when the component mounted right? So the example previously that I showed you with the cleanup function will actually replace the component unmount. However you can see now that it's actually a lot clearer to see that we can further optimize this because of the power that useEffect gives us. And we can actually remove this piece of code and just implement the additional on the mount only to make it further optimized okay? So this is extremely, extremely important and it allows us to go ahead and have that fine grain control over what our app does at different points in its lifecycle okay? So this was a fundamental part of class based components. And now as the industry is moving towards functional components, it's really, really important that you actually go ahead and understand how we can mimic this behavior in functional components with a lot more control and power behind it okay? Now just a little note to understand, we can have several useEffects. That's the first thing. So yes you can have several useEffects. And also multiple effects allows us to separate concerns. Right so one effect could be used for just console logging whenever a re-render occurs. Another effect could be used for attaching that window listener that we spoke about earlier. And you see every single one has its own little purpose right? Now I would highly recommend that you go ahead and practice this as sort of power allows us to increase the complexity of the app without increasing the difficulty of reading the code base. And it keeps it relatively simple okay? Now once you're done with this, what I want you to do is I want you to go over to your browser. I want you to go over to the React docs and I want you to go ahead and give the useEffects section a nice quick read okay? Now I make this a habit of every single time that you finish one of these tutorials you go over to the React docs, and you make sure that you give this a thorough read because yes we went over all of the 12 demonstrations however understanding the core fundamentals as to why these things work, why they're important is gonna be a lot more important for your future growth as a developer. So here it explains a few examples. It shows you the cleanup effects. It shows you the timings and the sort of ways that you can fire it for example, conditionally an effect based on in this case, the props.source okay? In this case, it's gonna fire off based on the source prop changing and so forth right? Now they have some important different notes that you should read, but I would make this a habit that every time we finish one of these lessons, you come over here, give it a nice quick read and that way you can solidify what we just went through today okay? So I recommend that you do this exercise, you code this out and you get everything working and test it for yourself. And yeah guys that's gonna help you concrete this knowledge and get good with it okay? So that was this lesson and it was a very important lesson on the useEffect Hooks. In the next lesson, we're actually gonna do something pretty fun. We're gonna build our very own custom Hook alright? It's gonna be a used random joke generator. So it's gonna be a lot of fun. It's gonna make an fetch to an API service and then it's gonna do some cool stuff with that. So until then guys, I will see you in the next lesson, carry on working hard and I will see you later Pap fam. Peace. ♪ I know how they love you now ♪ (exciting future bass music)
Info
Channel: Sonny Sangha
Views: 24,673
Rating: 4.9622917 out of 5
Keywords: react, developer, reactjs, html, css, js, javascript, papa, papareact, papa-react, tutorial, frontend, webdev, dev, clone, backend, fullstack, motivation, reactnative, react-native, redux, typescript
Id: UVhIMwHDS7k
Channel Id: undefined
Length: 24min 54sec (1494 seconds)
Published: Tue Jul 20 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.