5 Pro-Level React Do's & Don'ts

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] hi i'm jack harrington i've been a react developer for the past seven years and i've been teaching it here on youtube for the past three i'm gonna give you my top five react do's and don'ts and hopefully that should help you become a better react developer and javascript engineer in general let's get right into it so let's start out with a do do use functional components and by extension don't use class components i'm not sure why this is controversial now but if you're still using class components or you're just starting out with react i strongly recommend starting with functional components let me give you some reasons number one functional components are the future of react the only place you need to look is on their documentation site where it's really hard even now to find a class component and then on the new beta site it's near impossible to find a class component and it makes sense why because number two functional components have a much better state management mechanism than class-based components functional components use hooks and those hooks create a reactive state management model baked right into react using use state and use reducer you declare your state and then using use effect use callback and use memo you react to changes in that state and those five little hooks have created a vibrant ecosystem of super awesome hooks out there there are hooks for getting access to your apis for doing external state management for doing css animations everything you can possibly think of has a hook and you don't get access to any of that if you're using class-based components and then three and this may be counter-intuitive i guess it's harder to build applications using function components and hooks there's just a steeper learning curve so if you start there it's pretty easy actually to fall back onto class-based components if you end up being on a project that uses them so if you're just starting out or if you're currently using class based components i strongly recommend using function based components next up don't think about your react functional components as templates i mean they kind of look like templates i mean you imagine that this function generates some jsx and then that's it after that the jsx or the hooks kind of run on their own but thinking that way can be a cause of a lot of bugs so let's go take a look at a piece of code that demonstrates this template thinking in action so this is a user list and its job is to go off and hit this api where we get a list of users and then display that list of users so it's pretty simple and let's just start out with our first render we start out by defining some state we got our list of users that's good and we started off with a empty array which is great and then we start our fetch to our api and this is kind of where we get into trouble now some folks think that what happens here is that the fetch blocks the rendering that it's synchronous that it won't render out the return until the fetch returns but fetch is asynchronous always has been and always will be so what really happens is the fetch goes off and starts doing its thing and then we drop down into the return now here we have a div and then we have a map inside there we're going through the users but we don't have any users because we just have that empty array so we just return basically one div now eventually that api comes back to us and we convert the payload from that using json into javascript objects and then we set the users to those javascript browsers so far so good now template thinking would have us believe that there's some magic going on here that by setting the users this return section at the bottom is kind of run i guess by react on its own there's some sort of dynamic binding here but that's not really the case it's just a function and just like any javascript function when it re-renders it just runs the function all the way from the start to the first return or the end of the function so let's see what really happens what really happens is we first run that use date and we get back the users awesome good job on us and then we fire off another fetch back to that api so now we make a second request but we fall through to that return because the fetch is asynchronous and we render our list of users so it actually looks on the screen like we're doing well we're actually putting up the users on the screen but if we go over to the network tab we can see chaos as we are repeatedly hitting that api user's endpoint because we've built ourselves an infinite loop so what's really happening why is that happening well on that second render we get the response back from api users as we did before we convert it from json like we did before and then we set that users which again instantiates a re-render and you might be like ah jack you're a liar man what's gonna happen is that set users is gonna look at those two arrays and it's gonna see that the contents of those arrays are the same and it's just going to ignore it but that's not what actually happens a state setter is going to compare the old value with the new value using triple equals now in the case of a number or a string or a boolean you're actually right it's going to compare the value of those and not cause a re-render if the value is the same but in the case of an array like we have here or an object or a function it's going to compare by reference and even though the contents of those arrays are the same the references aren't and so that's what that state setter is going to key off of it's going to cause a re-render and you're going to get the infinite loop of course this is actually a pretty easy fix all we need to do is wrap this fetch in a use effect and then give it an empty dependency array which tells react that you're only going to ever run this use effect once on the mount of the component so you can see how this template mindset gets you into some troubles and paints a false picture of how react works so what is a good mindset when it comes to react to functional components well i offer this so the top section up here we'll call the hooks section and then down here in the return we call that the jsx section and the rule is anything in that hook section should probably be wrapped in a hook unless you absolutely know otherwise that it shouldn't be next up do use typescript when you're building out your react apps i've heard a bunch of different objections to using typescript in react and they usually boil down to one of three different objections so let's go through them the first one is that somehow typescript doesn't belong on the client as if there's some exclusive enterprise club where you use strongly typed or typed languages like typescript and that's just i don't know i i can't even justify that typescript helps you make more robust more reliable easier to maintain applications so why wouldn't you want to use it in your react app it has saved my butt so many times and i've only been using it for the last two three years so it's absolutely worth using typescript in the applications objection number two is that somehow typescript bloats my code at runtime which is absolutely untrue and i think this comes from the idea that say let's we have a function and it's got an argument and that argument is a person and it should have a first name and a last name and we put all that in the typing and i think the idea is that typescript is going to somehow inject at runtime some validation that makes sure that the person has those fields in it it totally doesn't do that in fact actually sometimes i wish it would do that and it doesn't so it absolutely doesn't bloat your code and then the third objection is something along the lines of typescript makes my code ugly and okay maybe that's got a point and it's a subjective thing i actually think typescript looks pretty good but let's see if the value of typescript in a react app is worth the potential ugliness that you think might be in the code so there are two times when typestrip really genuinely touches a react app the first is when you're defining your types like the kind of data shapes that come back from the server and the other time is when you're defining your react components so let's take a look at both of those and see how typescript does so we'll start off with defining your types so here we're going to define the payload for a service that's returning a list of people and it's got the urls for the payload and the page size and then an array of a person object that we define above that has all of the fields we expect in each one of the people that has returned from the server and they have their types their names and what this allows us to do is anywhere we use that person we can one make sure that we get all the spellings of all the fields right and if we change the fields we change them all over the place and we check all that at build time to make sure that it's always correct which is great and the other thing is check out that little question mark next address that tells typescript that address could potentially be null so it needs to check everywhere we use address to make sure that we're checking for null so say goodbye to those null d reference errors so now let's look at typing a component and we'll start by taking a javascript component and turning it into a typescript component so here we have a my list and that my list has two different props going to it it's got the list which is a list of people and it's got an on click and that on click is called whenever you click on one of those people and it gives you a person as the first argument and the javascript version has this as prop types but here's the deal prop types are only checked at run time which means that in order to check to make sure that every single place my list is used is used appropriately you can actually have to traverse through the entire application and watch all the console logs which is not great we want to get that done at build time so what we're going to do is we're going to first define that my list is a react functional component we do that by using react.fc and then within brackets we say the props that we have and that starts with list where we define that as an array of persons pretty easy and then we define our onclick now if you remember from the prop types the only thing we got to say was that it was a function with typescript we get to define what the argument is that goes to our callback which is awesome because when you're using my list and you're putting an on click on there you get hinted about what's coming back and all the fields that are on that person super super convenient and a much better way to define components so now all we have to do is just get rid of the prop types and we've converted to typescript not that bad and not that ugly that's what i'm talking about typescript is awesome and you should definitely use it to build your react apps this one's kind of a pet peeve for me don't worry about react rerenders too much i can't go by like a week without seeing an article on how to avoid react rerenders as if a react component rendering a second time is is terrible and terrifying and i'm not sure exactly where this comes from but you know let's take a component like this title component and it just takes a caption and it creates an h2 it's pretty simple stuff i think the idea is that somehow this component the jsx in there creates actual dom nodes that then react takes and just smushes right into its dom that's not the way that react works let's take a look at the transpiled code here so what's really happening is that we're just calling react.createelement and you give it the type of the tag you give it the properties you give it the children and then react makes a lightweight little data structure called a virtual dom node and then it takes that virtual dom node and it adds it to the virtual dom tree which is an in-memory representation of what the actual dom tree should look like and then it's up to react to actually traverse that vdom tree and then synchronize it with the real dom tree that's why it's called a vdom framework and it adds any nodes that it needs to add deletes any nodes that it needs to delete and it updates any nodes that are different than what's in the vdom but if there's no changes then nothing happens so i did a test a couple weeks back where i created a list and that list had 500 names in it each one created its own div and that first render yeah it was slow it took 100 milliseconds to go and create those 500 divs it's slow but the second render the re-render where nothing had changed was sub millisecond so you don't need to worry about re-renders so much in fact if you're getting a lot of renders it's probably just a bug it's probably a use effect that has gone into an infinite loop because of a bad dependency right but if you're legitimately seeing performance problems there are a lot of tools baked right into react to help you diagnose and fix those performance problems but my strong recommendation is don't fight the framework don't try to prematurely optimize your application by worrying so much about whether or not specific components are re-rendering do learn to love dependency arrays or at least deal with them or not hate them quite so much so dependency arrays are the arrays at the end of use effect use memo and use callback and they tell react when for example your effect should run so if any of the items in that dependency array change then your effect is rerun and use effect is the one that gives people the most grief so let's take a look at a use effect that goes off and gets some user data based on an id and at this point that dependency array is empty which means that if that id was set to a valid user id at the beginning this is fine it goes and gets the data but if that id was set to say no or something else and that id changes to another user id then this effect does not get rerun so what we want to do is add anything that this effect is reading from and put that in the dependency array so that's rule number one in this case that means that id but now you could say well why not just add everything in there let's go and add user and set user i'm just to keep all our bases covered right but what you created doing that is an infinite loop because in this case once that fetch completes you set user which changes user which again reruns that use effect so what we can do is we can add a conditional around that fetch to say if we don't have a user currently then run that fetch if that's the logic that you're looking for and that will make that use of the data that we've set in that use effect safe because now we've checked it and we make sure that we don't run into an infinite loop which is something that happens a lot when it comes to use effects so rule number two make sure that you check anything that you write in the use effect when you add it to the dependency array and then third there's actually a lint rule that handles all this and it's a great one it comes right out of the box with react lint rules and it tells you if you're missing any dependency arrays and i gotta tell you the number of times when folks have shown up on my discord and shown some use effect that's not firing or firing too much and it's pretty clear that the lint rules would have picked that up and you say well didn't the lint rules pick that up and the person's like ah i disabled that this was too chirpy don't disable the lint rule that's rule number three it's a great rule i use it all the time and i do react every day so another thing to watch out for when it comes to dependency arrays is when you have an array or an object or a function in your dependency array because react uses the same logic that it uses in that state setter to decide whether the value is the same or different between the old value and the new value and for strings booleans and numbers it does it by value which is really predictable but when it comes to arrays and objects and functions it doesn't look at the contents it does not do a deep compare like some people think it does it instead does a referential compare is this exactly the same array and i've seen lots of hacks around this i've seen people go and do join where they turn an array into a string or they do adjacent stringify to turn it into a string to do kind of a deep clone and compare but those are just hacks honestly the best thing to do if you're running into reference issues around the arrays or objects or functions that you put into your dependency arrays is to go find where that array comes from and make sure that that reference doesn't change unless the underlying data changes next up don't ignore use callback or use memo now there was some advice that went around about how used callback and used memo impact the performance of a react app that is absolutely untrue they are vital to the reactive state management model of react and when used properly to retain referential identity they can be a performance enhancement to your application so let's take a look at these two awesome hooks in isolation and the first one we'll start off with is use memo now there are two reasons why you'd want to use use memo the first is if you are computing an array or an object because those are maintained by reference and you want to maintain that referential identity and the second is if you are doing an operation that's going to be expensive so let's go take a look at some possible uses of used memo and see how they fall into our rules this first one is calculating a total from a bunch of costs so this is calculating a number which doesn't fall into our first rule about an object or an array but it could be a potentially costly operation because we don't know how big the cost array is okay so there you go that's a good reuse for use memo now the second example is where we have a list of people and we want to sort them so we're creating an array so it falls into our first rule and we're doing a sort which is potentially expensive so it falls into our second rule as well now our third example is far simpler we're building a full name out of a conjunction of a first and a last name and that's not good for either rule one you're building a string so there's no referential identity problem and two just really easy to do so there's no reason not to just turn this into a const right in line now let's talk about use callback so use callback also is good in two cases one is where you wanna keep your callback functions from being stale and two is when you wanna retain the referential identity of those callbacks so let's take this really cool name list component it takes a list of names and it takes a sort function and it does a used memo the right way actually it's got the names and it's got the sort function in there and it's only when those names or that sort function change that it's going to rerun that memo and do the sort so it's really efficient anytime that you're going to rerun name list it should not have to rerun that sort unless the names or that sort function have changed so now i'm consuming this and the way that i'm going to consume it is i'm going to invoke name list and then i'm going to give it my names and i'm also going to give it a sort function but i'm going to do it in line and here's the gotcha every time my component re-renders i create a new reference to a new version of that sort function now the implementation is exactly the same every single time but dependency arrays don't look at the implementation of a function they look at the reference to the function and so this is going to invalidate that use memo now it's going to sort on every single render even though names hasn't changed the sort function has so that's why the dependency arrays got tripped and that's why the used memo gets run the way to get around this is to use use callback and build the sort function that way and then when i pass it on i can be assured that every single time that i call that name list i'm using exactly the same sort function and therefore that used memo will not be tripped so as you can see these are vitally important hooks that you should not ignore so do make and use your own custom hooks so custom hooks are collections of hooks gathered together as a function that accomplishes a specific task and we are well on our way to making one of those over in our user list component where we have our use date and our use effect that work together to fetch data from that api and store it locally so let's go and create our use user list custom hook that has that use date and that use effect in it and then just return out the users now we can go use that in our component but potentially we could reuse that in other components and even better we can test that use user list custom hook in isolation which is awesome so custom hooks are a great way to get more reuse and build out a better factored and maintainable react application don't use redux just because when i first started over at nike all of our job wrecks were for react redux developers as if there were an absolute symbiosis between these two things you couldn't do react without redux and even then actually that was not the case you could use mobx or a bunch of different external state managers but a couple years back when we got custom hooks and the reactive state model built into react the idea of requiring effectively an external state manager like redux didn't become as important right you can now go and use context and hooks to maintain state globally and closer to where you actually used it so when you're thinking about building out your application and choosing your state management model my recommendation to you is to start with using context and hooks see how far that gets you it may actually be enough and if that's not enough then you're probably going to be making some api requests in which case you're gonna be using something like react query or swr and those are in effect state managers with their caches so that might be enough the combination of context plus react query or swr and if you're doing forms then formic and react hook form those also maintain state so the combination of those things all of those hooks might be enough of a state management system for your application but if that doesn't do it of course you could use redux although i strongly recommend using the redux toolkit if you do it greatly simplifies the redux development experience plus it's got a fantastic query library built right into it which is kind of the redux analog of react query but there are also other ones there's recoil and jotai which are fantastic atomic state managers and there's a new up and very popular one called sushdan if i'm getting the pronunciation on that one right it is essentially a kind of along the same model as redux just greatly simplified so there are lots of options now when it comes to react state management you don't need to go for redux out of the box but my number one suggestion to you is just keep it simple use as much as you need but not anymore and don't just use redux because you think you need to use redux speaking of query libraries do use a query library use something like react query or swr these are fantastic query libraries that do more than the happy path code that we created in our use user list right in our use user list we don't look for any errors we don't have any way to refetch stuff any of that react query gives you all that it gives you the status code gives you the errors gives you ways to re-fetch stuff gives you ways to refresh stuff on an interval it's fantastic it even has used mutation that makes it possible to go and do posts and it just super super simple so let me show you how we're going to go take our use user list and get it to use the use query hook from react query so first we import react query and then we're going to basically remove both the use state and the use effect and replace those with a use query where we give it the name of the cache basically in this case it's going to be the users and then we give it a function and that function goes and does that fetch and goes and gets that data and then translates the response into json so that's going to be our data that's coming out of our use query and then we just return that as the data but we get all of the advantages if we want to go and do things like refatch refetch on an interval all of those great features that are baked in to react query so my strong recommendation to you is if you plan on doing any kind of api access in your application is either use react query or swr or rtk the react redex toolkit and its query that's built in these are phenomenal libraries and you're doing yourself a big disservice by not using them or rolling your own here's one that's really near and dear to my heart don't build your own ui library react has an amazing set of awesome react libraries there's material ui there's bootstrap there's aunt d there's chakra there's mantine these are fantastic ui libraries that out of the box come with most of the controls you're going to need to put on the page plus they're accessible they're internationalizable they're themeable they're scannable they've got great documentation and examples and a whole user community around them that make it very easy to use them plus and this is almost as important or more important is many of these libraries in particular like material ui come with templates for a lot of designers favorite tools for example figma there's a figma template for material ui and it's great and what it does is it allows the designers to specify the ui not just in kind of boxes and all that with pixel sizes and whatnot and font sizes it actually allows them to drag on components from material ui and in fact theme it and then when they give you those mockups they're giving you exact call outs for those particular components with all of the props that you'll need and it's just a much better way to communicate between the design team and the development team and you lose all of that if you build your own ui framework so please please don't do that so how'd i do did i get your due did i get your don't please let me know in the comment section down below i really want to hear from you i want to know what do's and don'ts you have to pass on to other react developers like myself of course in the meantime you should go and check out my blue collar coder channel if you're interested in more videos like this i'm working my way up to a hundred thousand subscribers which is just a drop in the brad traversy bucket of course in the meantime thank you so much brad for the opportunity to be here i'll see you next time
Info
Channel: Traversy Media
Views: 152,393
Rating: undefined out of 5
Keywords: react, reactjs, react js, react.js, react framework, react javascript
Id: 4FhJkX18fS8
Channel Id: undefined
Length: 30min 6sec (1806 seconds)
Published: Tue Sep 20 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.