let's talk about best practices in react these days it's not enough anymore to know a little bit about react you really need to master it you need to know the things that you shouldn't do and the things that you should do so that's what I summarized for you in this video and for the examples I'm going to use this project here this is like a to-do app type of project so I can Mark these to-dos as complete I can remove them I can add more to-dos if I want and actually I just modified this from one of my course projects actually so some of you may already be familiar with the trackback project I just modified a little bit so that we can focus on the best practices and best practices are important because if you make certain mistakes it can sort of ruin the whole app so it's important for example that we structure the app in a certain way and that we make things reusable in a certain way right so things like structure reusability consistency these are all really important in order to create robust web apps and that is really what in my view actually separates a junior react developer with a senior react developer ER the senior react developers have internalized these best practices while the junior react developer will make a lot of these mistakes right so let's quickly go through them and I'll explain everything as we go all right so if you're ready let's get started now if you're building a product you're going to need analytics so let's say I have a dashboard here and so in this space of my dashboard I want to have some analytics some charts so that the user can gain relevant insights so I can include one line of code and what I will get here is the following this is made possible thanks to the sponsor of today which is is SEMA 4 so SEMA 4 is a more sophisticated solution for analytics so you can integrate it directly into your own software or app and you can customize its look so it looks like it's actually part of your app and let's say your user only wants to see orders that we're using same day delivery I can click on this and filter all of the data you can see all of these cards automatically adjust to what I just clicked right so that's pretty slick now your users will want to customize pretty much everything here so what they can do here with semop for is change the theme but also everything else like the order and layout let's say I want a little bit more like this make this sit more like this all right but they can also customize each card here individually so if I click on the icon here I can see all of the information for just that cart so here you can see the query for the data of that card I can change the data source can come from anywhere I can even write my query in natural language and then with semop for I can convert this with AI to a proper SQL query and here I can actually write SQL to get the data and very cool you can now also write python here so you can manipulate the data that you get back right here as well but let's say the only thing I want to do here is actually just change this from a donut chart into a bar or line chart now after I made changes I can approve the changes and now you can see I customized that card so now after reordering things here and changing this card I have a different view here or what semop for calls a lens so I want to save this particular view so I'm going to add this lens here right different order and a bar chart I'm going to save it so next time I come back I still see this default view or lens but now we have the third IC in here I can click on this particular lens that we just saved and now I get my view back and I can also set this as the default and all of the filtering and things like that still work as well right you can add semaphor with a single line of code so I would say check it out for your analytic solution whether you're building a SAS or e-commerce platform Financial or Healthcare type of software or any kind of software really and you want to give your users a sophisticated analytic solution and semop for recently released their AI feature so here for example we can chat with an llm and we will get some information here right so the user can just talk with an assistant essentially and get the specific data that are interested in and they can then actually add that here to the rest of the dashboard right so then here they can click on the button and it will be added with the rest of the cards right so very slick I would say check out semor you can find a link in the description the features that I just showed you were just the basics you can do much more so I would say check out seop for's website you can find a link in the description and make sure you sign up for the weight list all right number one is about hardcoded values or what people sometimes also call Magic numbers or magic strings so let's say here in the ad a to-do form that I have here let's say I have a component for that the add to-do form right makes sense and in here what we want to do is we want to keep track of whatever the user wrote right just keeping track of that and then here when the user actually submits the form we want to add the actual to-do to the list right so if I type here add to-do it should should actually be added to the list here so we are hooking into that submit event that happens on the form when you actually click on a button in a form and if you remember it will by default the browser will try to sort of awkwardly refresh so we prevent that and then we can do something like this where we try to set it where we try to add it to all the to-dos I removed some things from here just to make the example that we talk about a little bit clearer that's why I have some red Squigly lines here but that's okay but something like this right now before we actually update the to-dos Maybe what we want is we want to monetize our app so a free user a guest user can only add three to-dos if they want to add another one a fourth one they need to be logged in let's say and maybe even on a particular subscription plan but for sure logged in right so what we want to do is we would want to do something like if the number of to-dos right so to-dos do length if that is already three right is that if if that is three and the user is not logged in right so something like is authenticated right we could use some authentication solution and we will know if the user is logged in or not let's say that's not the case then we want to alert something uh something like this you need to sign in to add more than three Tod do so this will work now the thing is that here we are hardcoding a value the number three is that a good idea to put the number three sort of in the component here is this going to scale well which means if I create potentially hundreds of more components that also need certain values like this is that a good idea so I would say it's not a good idea I would say it's a better practice to Define these hardcoded values somewhere else so that they're easier to manage let's say that we do it like this and now later I decide you know what a free user should be able to add 10 to do so now I would like to change that so now I have to remember oh yeah where did I leave that number again right so now I would have to I would potentially have to open up a bunch of components cuz I don't know exactly where I left that right so when you're hardcoding these values sort of deeply inside your component componentry to manage all of that so I would say it's a better practice to Define these constants or hardcoded values or magic numbers or magic strings to define those outside the component and typically these are written in capital case right we could call it something like maximum free too right and then you would use that variable instead of the actual hardcoded value here and I could even make this a template literal so that we actually have a nice Dynamic string here right something like this and now the benefit is if I you know manage the app and I'm like yeah maybe a free user should should be allowed to add more than three well now it's a little bit easier to find it's now at the top of the file instead of you know somewhere deeper down here so that's already an improvement I think that it's at the top of the file but I think it would be even easier to manage if we actually put this in a dedicated file together with all the other hardcoded values that we're going to use so what some people like to do and what I also like to do is actually create a separate folder and we'll talk about folder structure in a second second as well but what I like to do is I like to have a folder here for components and then here I have one that I call library and I have some things in here already but one of the other things that we could create here is simply a constants dots file and in here I can put that right here now if I want to use it in another file I do have to export it and then if you want to use it from another file I can remove it from here I do have to import it from there so now this will work the same but now it's not in a component file or even in the component it has been extracted out of the component and it will now have its own dedicated file so now if I want to change something like that I typically business logic type of values I know where to find them cuz I have a dedicated file for them and I can easily change it to 10 here and everywhere where it's used it's automatically updated right that's another benefit by the way which is that if you leave it at three right so if you do it actually like this where I'm actually using it in two places here now let's say it should actually become 10 right so if I hardcode it like this I may even forget that I have the number three here as well but if you actually use variables for this stuff if you actually make a change to 10 here it will automatically be correct in all the places where you use it right so maybe a bit silly but I think it's good to uh talk about that this is a number value but some other examples could be for example if we want to check if the user is uh is actually writing some sensitive words in their to-dos for example right just a just a silly example here again we are hardcoding these two words now password and credit card right so if the user is typing the those maybe we want to give a popup or maybe give them a warning or something maybe not even return but let's say something like this so now I'm hardcoding these two strings here but what if we notice that users are leaking other sensitive data and we want to add more words let's say so now I have to find oh yeah where did I kept that list of sensitive words well it's going to be buried somewhere in some component here also not great it's easier again to manage that outside the component these two hardcoded strings right so it's easier to just have an array let's say of let's say sensitive words right so here you define all the words that are sensitive so if you want to add another one well you know where to find it and you can easily manage that here and so then here you can just check if that array of sensitive words if that incl if the content if the content of the to-do is included in that something like that so now I have one file where I manage all of that those hard hardcoded values instead of burying them randomly scattered throughout my component tree and also if I do change them wherever I use those constants they are automatically updated it so every instance will automatically be up to date as well I think that's another big benefit one other example I want to give you here has to do with when you initialize the state for example so here we want to keep track of the to-dos right so that's a piece of data that we need to keep track of over time that we want to change so that is a good use case for use states that is indeed what we're using here in the app now I again I changed something so we're going to have a bunch of redly line so let's say we have some states here for to-do so here initially now it's going to be an empty array maybe I do want to to start off with some initial to-dos and this is also something that people will often Define in a constant so what you could do is you can say initial to-dos something like this so here I defined initial to-dos and then I can use that to initialize the states right so here you also have sort of like a constant and I defined it outside the component here right so the component is just that function right that's the component and um it's not the file right so this is just this is just a file but the actual component is just the JavaScript function essentially in react now I could Define it also inside right so sometimes you have arrays and objects that you want to Define somewhere technically I could do it in the component I think it looks a bit messy and also it's not a huge problem but it will be recreated on every render right so every array or object that you write that you define inside the component function here will be recreated when it reenders now for a small array like that that's not a problem now if you have a bigger array or object it could be performance issue in that case and also if you use an array or object as a dependency for example in a use effect dependency you're going to since you're going to recreate that object or array every render it's going to be different every render so as a dependency it will it will not behave as you want because if it's a dependency and it's different it's going to R trigger a run of that use effect for example right so typically when you define these constants for arrays or object you typically also want to do it outside the component and maybe also in a constants file here for this one I can of like if it's close to where I actually use you state but that is more subjective all right let's quickly talk about best practices for folder structure I noticed especially beginners they worry a lot about folder structure and the truth is that you don't really need to worry about it there is no one you know good folder structure and all the other ones are bad the most important things are that you're consistent with your folder structure and that it makes it makes sense so the way to think about it I think is if a new person joins your team is it easy for them to understand what's going on and if it's easy for them then it doesn't matter how you exactly structure it it's okay now what I like to do personally is I like to create one big folder for all my components so here you can see I have a bunch of components here as your app grows you will add more and more so then you can add subfolders in here right so maybe all the components that have to do with the header I'm going to put them in a header folder right just for organizational purposes I would have an actual header component but I'm also using the logo component only in the header so I would also put it in there for example right so you can then further divide that if you want or by feature right so if you have let's say authentication feature so all the components that have to do with authentication like the auth buttons maybe a profile component you're going to put that in a separate folder within here something like that now typically you also have a folder for State Management so in this app here I'm using the context API for managing state in particular the to-dos actually so the to-dos are managed from a context provider component now technically I could have multiple other contexts I can create a folder for that that's why I named it plural here context if you're not using the context API but instead you're using something like Redux or two for State Management in that case you would not have contacts you would maybe have stores right so you would have a store for your data yeah that's typically where I have another folder for so then here we have a folder Library so this is essentially a bunch of uh utilities essentially right so here we already saw the constants for file typic also a file for Hooks and actually also typically a file for your helper functions or UTS and helper functions or utility functions they mean the same things like for example if you're very often in many cases in your app maybe you want to capitalize the first character of the of the to-do and you do it in multiple components well maybe you want to have a function capitalized string right that's a utility function or helper function and you can put that in a .ts file I had something like capitalized first letter so you can use this wherever you want in your component you can just pass in a word or a string and it will just give the same word back with the first one being upper and then I have a file here for hooks it's actually the same I would say as a typical utility or helper function the exception is in a hook you are using a react hook like use state or use effect so typically people put them in a different file called hooks right and we call those custom hooks but they're very similar to a normal utility or helper function and then also you would have a file for your type right so here we would have a to-do type that we would have to use in multiple components we'll talk more about typescript in a second because I consider it a best practice as well but I think this is a good folder structure to start off with now as your app grows bigger and bigger usually you're just going to add more subfolders in here right so here maybe we're not using tillin CSS but we're still using a separate CSS file for each component right so in that case I could actually uh create a uh folder just for that component and then I would have a test file for that and a CSS for that and that would be just one component there are no hard and fast rules about folder structure so don't worry much about it but as a best practice you want to make sure that it's easy to pick up for a new person and it's going to be easy if you are consistent things are split by some semantic purpose right so a component is different from State Management and State Management is different from you know constants and types so these things are separate from each other they're distinct and so they are organized differently okay but uh I wouldn't worry too much about it over time it it's pretty obvious what works well and what doesn't all right now let's talk a little bit more about components as a best practice let me actually remove this we actually do want to create many components actually so when should we create components so you have to imagine in the real world what you're going to get is some design from a designer typically right so there's a designer and they use a program like figma or some other design program to create an aesthetically pleasing design and they will give you that design and it's up to you as a DE veler to convert that into working code so you will receive some kind of like image almost of this design let's say we want to create a react app out of that actually works right so that you can actually type here and actually you know submit something and so it's actually added to the list now in the world of react it's all about components right so what you want to do is you want to organize the app in components and a component is just an independent piece of the UI essentially when I say UI that's a user interface right so it's a user interface because as a user I'm interacting with this to update the data right in this case the to-dos what we want to do as a developer is of this UI what are the independent pieces that make up the entire UI here and importantly which pieces are we going to reuse right so reusability is something that you're going to hear very often now in this app for example we have these three buttons so I have one here for add to list but I'm actually using the same button component for these two as well right so for the login and register as well so in react you want to look for opportunities where you can reuse certain markup for example like jsx essentially and styling and that's the case here right so the markup the actual jsx and The Styling is going to be very similar for these three buttons so it makes sense that we try to create one reusable button component for them and it has many benefits if we now make one change if these buttons need to have a different border radius for example I only have to update it in one place and wherever I'm using that button component it will be be updated properly and there are many benefits to reusing one component when you can so since the differences here are very small and subtle it makes sense that we try to put that in one component now in practice though realistically there are going to be many components that you're never going to reuse for example I have a sidebar component for the entire right part here I'm never going to reuse that but I still created a component for that just for organizational purposes same for the header here right I just have one header component and I'm never going to reuse that but I still created a component for that because it's just better for organizational purposes right so as a best practice you do want to create a lot of components certainly for things that you're going to reuse I would say even if you're only going to reuse it once I would still create a separate component for that but also in addition to that you want to create components when it helps you with organizing the markup and the jsx even if you're never going to reuse it so just as an example here in the app if I scroll down here you can see that here well this is actually pretty easy to analyze right you can sense that this is well structured I have a component here for background heading right that's actually this thing behind here if I open that up you can see it's actually just an H1 right with to-do app here it's styled in a certain way so it looks a bit cool here but you can see I'm never reusing this right so I'm only using this in one place but I still put it in a separate component because if I now want to see how my app is structured I can just go to the app component and here I can see oh background heading so I can I know what this is because of the name of the component here right this is much better than if I didn't create a component right so if I just copy and paste this if I just have an H1 here you can already sense that now it's a bun it's a bit Messier already right so here I have a bunch of extra markup now yeah I see it's an H1 but what does this H1 actually do whereas with if I actually make it into a separate component now I know oh there's going to be some heading and that's meant for like a background heading so there's more semantic there's more semantic meaning that I can extract from this and it cleans up the component a a little bit more and the same is true for the footer here for example right so if I open up the footer here you know there's a bunch of markup here it's just for the footer here that we have at the bottom and it's just a bunch of markup essentially I'm never reusing this right but this looks much better than if I would put it right in here right you can see the app becomes much more Messier if I put all the markup and so instead it's much cleaner if we just make a component out of that and the same for header and sidebar right header sidebar and the to-do list as well I'm not I'm not reusing that anywhere right I'm only using that once but it's nice that we have separated those things out into a separate component just for organizational purposes I could do the same with the main here right so here I have a main element just for the layout here I could technically create something like main the only downside is now um it hides the other three things that are actually going on like the item list like the to-do list and the sidebar so now I would have to open up the main file to actually see what's what's going on there so that's a bit subjective where you want to draw the line but I think it's um I think it's better to keep it like this because now with just opening up one file I can see pretty much all the main parts of the app the to-do list the sidebar I can see everything from one place here so as a best practice if you can improve the organization of your code by creating a component that's a good use case for creating a component and in addition to that if you have some kind of reusability where you have let's actually go to those buttons and so here we have the uh button uh component we don't really have to understand what's going on here the point here is we're going to have some jsx essentially here this button tag only but also a bunch of styling right you can see there's a bunch of styling here that's going to be shared for these three instances all right now about the button it looks a bit chaotic because of all the class names here but you can see we are using one component for these three instances so here in this form we have add to list if I go to that form component you can see here I have this button component and also here in the sidebar right so then here we have a similar button it should just be a little bit deemphasized because this is not the main action that the user should be taking right this is the main action these are like secondary actions so here in the sidebar here I have these buttons here it's the same component but we can customize it in a certain instance with props so you can see I can pass here button type is secondary right so here in the component we get button type and then here based on that type we can just change this The Styling a little bit right just making the opacity a little bit less so that it looks a little bit deemphasized and then also of course the text in the buttons should be customized so in react what you can do is you can use the opening and closing tags of a button and then whatever you pass in there so in this case just text whatever you pass in there you get that as a children prop this is like a special prop and that's just going to be what we what we display in between here so that's why we can show different text for these instances now when I click here we should submit the form but when I click here we actually want to do something else so here there's actually some interactivity or some logic that we want to run but it should be different in each instance so you can see here when we click it we just want to run whatever gets passed in here when you actually use the component we'll talk a little bit more about this later but it shows that we can not only customize The Styling or the jsx or the actual text in a particular instance but also the behavior when you actually interact with it right so I would say don't be afraid to create components as a best practice try to identify opportunities for reuse as well as when some element in the UI is distinct from something else right so here this logo thing is different from the to-do list here so those probably should be in two different components all right let's talk about the next best practice which is to avoid unnecessary div so I see this a lot let's say we are actually creating a new button component we already have one so let's say so let's just say BTN TSX cuz we already have one but just as an example let's let's say you're creating a usable button component very often uh people will create a component maybe with an extension like I was just doing right now and you will get some boiler plate like this and then they will return a div and then in there they will return so for some reason people uh keep the div in here but that's not necessary in fact it actually has some downsides so we actually do want to remove it and since we don't need them I can just directly return a button element like this I don't need a div around there it's not like a component always needs to return a div or something like that right so we can we can just leave off the div right now here in the sidebar component we have those two buttons right so here we have these two buttons and uh there's actually some space between them vertical space so we have uh a little bit of a gap in between here so until wi I can use this class for it but doesn't matter whether I'm using this space y utility class from Tailwind or maybe I'm using flexbox or css grid it could be some layout styling here so we can actually get a gap between them okay so far so good now what if we actually want to have some uh check here so if the user is already logged in well we should not see these buttons but we should see a logout button instead of these two right because we don't want to show log in when we're already logged in so here we want to check if the user is authenticated we can have some logic here so if the user is authenticated if that's true we want to show a button component that is going to be for log out right and if the user is not logged in then we want to show those two buttons that we have here right um now as you can see we run into an issue here because in react you cannot return two things and so here I'm actually returning now as the else part of the turnery here I'm returning two things two components here you cannot do that you always have to return one one one thing also when you return from a component so here it may be very tempting to use a div right you think oh I need to return one thing so I can just wrap all of this in one div and then you're just returning one thing which is that div which in turn holds these two buttons right so now if we do this we get rid of the red squiggly line but now if you go back you can see we actually screwed up our layout here and that is because we are adding an unnecessary div here this div is not necessary because we can actually also use a react fragment which will not add anything to the HTML structure of the page so this is a special thing we can do in react if I do this we don't have any red squiggly lights and the layout here is preserved right so when you're adding unnecessary Dives here it will clutter up the HTML structure and the biggest problem with that may be that you are essentially breaking up the layout right so the layout styling here also with flex box with CSS grid it depends on the HTML structure so if you add a div in between there you may have a problem with the layout right so if you don't need a div when you can just use a react fragment try using react fragment and in addition to that if you add a div sometimes you want to inspect here in the div in the browser Dev tools as well and if you add unnecessary diffs in here you're going to clutter up this part as well so it will make it more difficult to understand what's going on here as well so if you can try using the react fragment which is just this right which will preserve the layout because it does not add anything to the HTML right so if I go back here you can see I have a div with space Y2 and then directly in there I have these two buttons right so this div now is still the parent element of these two buttons because this does not add anything to the HTML structure you can also write it like R do fragment if you want but uh T typically people pre prefer the short hand like this all right so I have one very important one which is don't add layout styles to your reusable component so I could take the button example from the previous one but we actually ran into this with my evento project in my react and nextjs course we ran into a very clear example of this so we have the homepage where we have this H1 but we we want to have this H1 on other Pages as well so here on the uh this page here I want to have the same H1 events in Austin right so I want I want the same H1 so I want to reuse that right so I'm using it on multiple Pages I'm using it in multiple places so here we create an H1 component and basically it just has some styling here so then here on the homepage I can just say H1 and then whatever text I want in that particular spot I can just write it like this and then it will just pass it along as children right so we've seen that before with the button but I also want the H1 on the other page so here events in Austin here I want the same heading so here I can just use H one and then I can just write whatever text I need in this particular spot all right now what's the problem here well the problem is that here the H1 looks good and the H1 here itself looks good as well but you can see there is some issue here with the spacing here so here these cards are directly sitting almost against the H1 here so what I would like to do for example is I want to add some margin to the bottom of the H1 here to push this stuff down right so you may think oh this is this is the H1 I want to push this down whatever this stuff here is I need to push that down a little bit so I want to add some margin on the bottom here well that's the H1 so I can go here so I go I go to the reusable component and I'm going to add the layout Styles here so here I'm going to add some margin to the bottom right so now if I save you can see indeed we have fixed the problem here but if I now go to the homepage you can see we have another problem here because remember this is a reusable component so it may work for one particular instance here but now the margin on the bottom is also added in all the other instances where you're using it so here on the homepage uh here we now also have that margin and here I don't want that so this is actually quite a common issue that I see is people they add layout styles to a reusable component which is not what you want to do because it will affect all the instances where you use it so typically you don't want to add margin to a reusable component like an H1 or a button you also typically don't want to add Flex box styles or css grid Styles you typically don't want to have that in a reusable component so you want to remove it from here which will make this look good look good again but now of course we still have this issue so how do you solve this well I could of course add a margin to the top of the other component here right if you have some other component and you can add margin to the top there something that's not reusable that would be okay now that's still not a great solution here because here I'm using events list I'm using suspense but that doesn't have an effect here but I'm using events list and I also want this to be reusable so I also don't want to add layout styles to this component here so what you what you may want to do you essentially have two options you may just want to add a oneof div so in this case you may actually do want to add a div to the structure because what can I do here I can just add the layout Styles particular one right margin bottom 28 so now it's just a oneof div essentially that will contain all the layout styles that I just need for this particular instant now you can see this is fixed because the margin has been added but here we we we still have the same style so here there's no problem we have fixed the issue so you can you can add one of div if you need specific layout styling around a uh reusable component that's one option you have by the way you cannot use a react fragment here right so react fragment does not allow you to add Styles or something like that because it doesn't get added to the HTML structure so here we actually do want to add a div now that's still not ideal that we have to you know add a div here it's it's okay this using a oneof div I think is fine but I think there's even a cleaner solution so what you can also do is we can remove this and it would be nice if we can just treat this like a normal H1 element where you can do for example class name right I can just add margin to the bottom 28 here if I could just do that for this one right so if I could use if I could do something like class name margin bottom 28 if I could just do it for this particular H1 and not the other one here just this one here that would also fix it if that would work right so can we make this work and the answer is yes actually so this H1 we can actually just accept a CL class name prop and we can modify the H1 component as follows so we're going to accept a class name prop actually it will be optional cuz here for example in this H1 we don't want to add anything so it will be opt optional we will still have our base Tailwind classes right s the base styling but in some instances like here for example we want to add one we want to add an additional class in that particular instance so we're going to take the class name and we're going to merge it with the base classes here this is easy to do with a utility called well the CN utility this it has been made popular in recent times thanks to Shad CN and it looks a bit complicated here I will not explain it here have a separate video on that basically it's using clsx and till wind merge to intelligently merge whatever you're passing in with the base classes here right so essentially now if I would if I would inspect this here you can see here in the class list here that MB 28 has been added to this list of classes here and therefore yeah the issue here has been resolved while not affecting the other instances right so this is one of the solutions you may want to prefer I prefer this because now we can keep the component reusable while still having a oneoff styling in a particular instance without creating unnecessary divs or affecting the reusability of the component so as a best practice try not adding layout styles to your reusable component instead if you need if you need some kind of layout Style just use a of div or use the class name prop like this all right so I also think as a best practice that you should use typescript typescript makes you code a little bit more strict it helps you catch your mistakes a little bit faster as well as it will give you intelligence as you use for example a component so just to give you one more example here with these buttons so here if we go to these two buttons one more time so here uh I'm using those two here right so here I can pass a prop here button type is secondary and we can accept that here and then based on that style it a little bit differently now you can see so far I've been using TSX right so it's basically the same as jsx but it has some typescript features here and that's also why I had some red Squigly lines so far so for example I have some red Squigly lines here because I have not typed this basically the props of this component we haven't specified what type this should be should button type be a number or a string so here I can specify button props I can I like to extract this out into a separate type I can say type but some props uh so here by using typescript I can make myself a little bit I can make it a little bit more strict for myself so I want to say the button type well we could say it should be it could be any string but we can be a little bit more specific typically you want to be as specific as possible it should only be the string primary or the string secondary so we use a union type there now for on click and the other ones uh on children is not important for now and basically on click should just be some function and children is something called a react node this not important for now I want to show you why I I want to use typescript here so now that I have properly typed this you can see the rri lines are gone but what is the benefit of doing this well now if I for example make a mistake cuz I think oh yeah should it be uh second or should it be maybe it's an info button or was it button type off you can see when I make these when I do not get the right one so if I'm just guessing here it should be an off button type which is which is which is wrong typescript will warn me with a red squ line here and so you can see type O is not assignable to type primary or secondary so now I know ah okay so this is incorrect so I can remove this and if I want to see actually what option I have I can use intelligence here so here on Mac I can do option escape and it will actually tell me that I can pass either primary or secondary here here we also need to specify what we want to do when we click it if I forget to do that so if I just remove it from these two so if I just remove it from here you can see TP warns me as well because now it's say hey onclick is missing right so here on click is missing missing so I can fix my mistake oh yeah I need to specify something for on click and also sometimes you use a component uh maybe I'm just using the button here and I know I need to pass some things I'm not sure which props to pass so again I can use intelligence here and it will tell me the things I can pass here so button type children on click and key with a question mark is actually optional right actually we we actually want to make button type optional as well so I can just add a question mark here but the point is here typescript helps you typescript will warn you when you made a mistake and also gives you useful intelligence information if you don't know something so in the world of react you'll see it a lot with props for a component as an app developer you don't have to become an absolute typescript expert but for props and sometimes use State and some of the State Management Solutions those are some situations where typescript comes in really helpful actually and so I would consider it the best practice to use typescript now by the way if you really want to master react and nextjs I highly recommend that you go through my professional react and nextjs course it has everything that you need to know and we start from absolute scratch and by the end we're building some pretty sophisticated react and xjs application so highly recommend you check it out you can find a link in the description all right another best practice is to keep your components dumb so what that means is you want to keep them simple essentially so as an example let's say that we have some kind of status bar here at the top so if I check off one of the to-dos here then we see this one being wide for a third and if I have two out of three we can see it's like 66% and then if I mark them all as completed it's 100% white right so this is some kind of status bar component so we could hard code a number here let's say 50 right so then we would have 50% right so here if I would write 50% then it would always be 50% right now what we want is based on how many are how many to-dos are actually completed that's how wide it should be right so here um I'm making a calculation so here what I'm doing is I'm taking all of the to-dos only take a look at the completed to-dos so that filter will give us a new array and we take its length so this will be the number that specifies how many to-dos are actually completed we divide that by the total amount number of to-dos and then we multiply it by 100 to get a percentage rent then I'm just tching on a percentage sign at the end and so basically what we're doing now here well we're not making the component simple we're actually doing a you know pretty complicated uh calculation in here and if I do this if I now refresh here you can see it actually work works as expected but I would say this is not really good component Design This is not a best practice because in order to make this calculation we need access to all the to-dos so we need to pass down all the to-dos here as a prop in order to make this calculation which is not a good idea because let's say we also want to use this status bar for when we're loading data let's say let's say we're fetching data from somewhere and that may take some time and while we're waiting we want to show like a loading indicator with this status bar or for example maybe we have different pages and I want to show a loading indicator for transitioning to another page right so a page transition may take some time and I would like to show like a loading indicator with this status bar as well but now the way that we've designed this component is it's always going to use this todos variable here and the width here depends on that calculation that we're doing here so the problem essentially is we've made it too specific to one particular use case which is a status bar for the to-dos for the amount of to-dos that are completed and we cannot really use it now for the other possible use cases like a loading indicator for fetching data or page Transitions and this is actually pretty common so what you want to do is if you have a calculation like that you don't want to do it in here you want to do the calculation higher up in your component tree and you just want to use this component by passing the percentage that should be its width so here we can just say uh progress percentage and that's the only thing you need to pass in so you do the calculation somewhere else and then here we will just use that variable like this right so now it's more agnostic to a particular use case it's more General now I can use it now for the to-dos how many are completed so how would I use this now well let's say we're using the status bar here in the app component and let's say that we have the state for the to-dos right here now if I want to use the status bar I should not be passing in all the to-dos it now accepts one prop the progress percentage so more General and how much should it be well if it's for the use case for the to-dos we can make the calculation in here right so here we can say to-dos completed percentage or something like that and we can do the calculation in here and then here we will get some percentage and I can pass that as the value here so then what you get here is going to be something like 33 or 66 or 50 then the width will be correct and now if I want to use the status bar somewhere else and actually I can also write it like this you know just immediately in here like this uh remove that so this would technically also work but now the benefit is I can also reuse this component for other use cases for example for a loading indicator right maybe we're fetching some data and we're calculating the how much loading time is left something like and here I'm just saying is 50% or 50 um but we would have some calculation for that and now I can use this component for that as well and then it would show how much how much uh percentage and then it will give me an indicator here how much uh is Left Right but the point here is that this component is dumber now right not as an insult or anything like that it's just it's not as complicated as before because that very because if you have a very complicated thing it's usually very specific to a particular use case so we have made it more General now and as a result of that it's more reusable keep your components especially if they're lower in your component tree or if they're reusable make sure they are dumb they are not unnecessarily complicated they're as simple as they can be which will improve their reusability and I think overall structure of the app right let me undo this right and typically that means if you have some kind of calculation or something that you're doing here which is essentially derived state right so this is essentially this this information here to to do is completed it's essentially being derived from some existing state that we already have so people call that derived State typically you want to derive it just very close to where you actually have the original state and instead of somewhere down in your component Tre you want to do it very close to where the where the actual uh state is and then you can just pass that as a prop and actually here we should do probably times 100 right so then we have the same calculation as before right so uh I would say this is a better structure so now we have made this component uh simpler again all right so that was one example of having a component that was unnecessarily complex there are some other situations where that may be the case so let's say we are managing this state here and when I submit this form here we want to update the to-dos we want to add one to that array so maybe you would say well set to-dos we need to set the to-do somewhere actually in the form now that form is actually sitting in the sidebar component here so here you can see we have the add to-do form right and Below there we have these two buttons I removed some things sometimes I'm changing some things just to keep the example uh clear so if you see something that has changed that is why but I think here we understand the idea which is is then what you may decide to do is you want to pass down that Setter function right so very common for junior developers you pass down that raw Setter function that we get from US state to the sidebar right so then here we need to accept that as a prop and then here we can pass it to the form right so right and then in that form component you would accept that Setter function as well and then here when you actually submit the form is where we could actually use it right so then here when we actually submit the form what do we want to do here we want to set a new array with all the previous to-dos basically update the state in some way right so you would uh add the new to-do in that array right we'll talk about that in a second as well how to do that properly because we don't want to set it to an empty array of course but let's focus on the fact here that we're doing prop drilling here right so to get that Setter function all the way from where we're actually managing the state all the way down into our component Tre to the component that actually needs it you could say we have to go through one in between component which is the sidebar component here which only accepts this as a prop just so it can then pass it down to some other component the sidebar doesn't needs this function it doesn't need this Setter function the sole purpose of this prop now is just to pass it down and this is not ideal because now we're making this component more complicated than it needs to be right so now we've created sort of like a chain from app to sidebar to add to-do form and now if you add another component in between there well you have to make sure you you also pass the setter to death and if you don't do that you break the chain right so it becomes more like a fragile setup so we are again unnecessarily making a a component complicated because we can prevent prop Drilling in several ways actually so people are very quick to use a state management solution like the context API or two or Redux and those are actually all fine solutions to prevent prop drilling nothing wrong with that but there is actually also an easier way we can remove this and we can just have opening and closing tags and what you can do actually is you can then take all of this stuff in between here and paste that right here of course I would need to import the components in that case make this a little bit wider yeah so now the sidebar will just receive all of this in between here as children right so we've seen the children prop before and we can now replace all of this with just the children right just passing through the children here so now the sidebar as you can see is much simpler we don't have to pass it as a prop to sidebar first we can directly pass the setter function to the add to-do form here because it's already here in this file right so you can use the children pattern to prevent that prop drilling as well right and in fact we can do it for all the other components in here as well for example in the header here we have logo encounter right so you can actually take this for a small app like this you may actually just do this for a lot of these so you would have logo en counter in here as well and so you would you would essentially have all your components just in this one app component like this it's one approach you can take now one downside of this approach is of course that the app component does blow up right so you can see it's already a little bit more Messier now and bigger and it's a little bit harder to see what's going on now but that is one option you have to prevent prop drilling right so you can use that uh children pattern and just uh immediately pass the prop to the component that needs it like this now you can see everything here still looks the same because it works the exact same as before and actually there is one performance Improvement as well which is that this component now the sidebar if it has some state of its own or if this has to reender on its own previously what we had was all the other components in there would then also have to rerender however with this pattern if we keep it like this if the sidebar needs to render because it's it has some state for example it will not cause a render of the components in here and so there's also a performance benefit in that Cas it's not the case in in this example but uh I think that's good know as well the only downside is that the app component becomes a little bit more bloated if you don't want to do this you can also use the context API uh which is actually what we're doing in this project in the course or two or Redux they all work very similarly it's all it's all the same in in essence those are all more like State Management Solutions before you even go there for a small app you may want to consider following this pattern first and see how you like it and actually if you take that pattern and you do it for the entire app we actually do that for the remote Dev project in the course and this is actually what it will end up looking like so you you essentially have a a bigger app component but the benefit is you can see everything that's going on in one component here right and if you were managing state in here as well you could pass that as a prop directly to the component that needs it without passing it through header and then header top first you can pass it directly to this bookmarks button for example now typically for State Management you want to go for the context API or two St or Redux we talk about that in the course as well um so that's why you don't see that here but um you can still have it like this and I think it's actually fine right so I I I really like the children pattern actually because it gives a nice overview and it prevents prop drilling now for this video I'll actually leave it like this so uh it will just be the children pattern for the sidebar here this this portion essentially and I will just leave the other ones like they are right now uh so let's continue like this all right next one I want to show you also has to do with uh keeping components as simple as possible so from this form component we want to update this state right so when I actually submit a Todo there is a submit event right that's what we're hooking into here now we're going to prevent the default because we don't want that refresh but then we actually of course actually want to update the states so we need to take whatever the user wrote and actually add that as a to-do right so what you want to do is we want to have a new array of course but we want to keep all the previous to-dos as well so you would probably spread them out uh like this and then we would create a new object for the new to-do right so we would have maybe an ID maybe the to-do not length or something like that plus one the content and is completed by default is false and so this is one way that you can update State you you have new array but you spread out the all all the other ones so that we keep the old ones and then we add a new one right now the the problem with updating it this way is that now we need access to the to-do variable right so that is state that is not managed from this component that's what we're managing up here right this is just an example I'm changing some things along the way to keep the examples a little bit simple but the point is the to-dos here is manag here right and we're trying to update it from here in this way so we need access to to do variable now you may be inclined to just pass that as a prop as well right basically uh you're not really thinking about a structure you're just passing props whenever you feel like you need a variable so then here you would accept the Tod do like this and then uh you can see it technically Works uh because now we have no redly line here anymore the to-dos are actually available here now this also makes the component unnecessarily complicated we don't need the to-dos here because State because with react use State there is another way of updating state which is with a function right so instead of using the to-do variable you actually get the you get you get all the to-dos with this updat function right so we can take all the previous to-dos we can just spread them like this right so here we can also use previous that length so now I'm not depending on the to-do variable I can can actually remove it as a prop we don't need to pass it as a prop and here we can also remove that as a prop as well right so this is a bit of a simpler one but sometimes I still see this with react use State you have two ways of updating State you can use the the updator function or you can just use it like we did before but generally speaking you want to prefer this functional way of updating the state when the new state depends on the previous one right so here we want to keep all the other to-dos so the new state depends on that so we can use this also very common for counters right count plus one whenever it depends on Old State try using the uh updat function all right now a little bit more about passing down a Setter function like this I see this very often but actually it's not what you want to do in my view I think this is also not optimal uh because very often when some event occurs like submitting a form here we want to do multiple things so for example we want to add the to-do to the list okay that's what we're doing here with the actual Setter function but there may be other things that we want to do for example maybe we have some kind of model and we want to show a message to the user in that model after adding it to the to-dos so we we may have some State for the model we may want to say something like uh you have now added well you have now added to-dos do length right maybe uh some amount of to-dos please upgrade to Pro to add more right so we want to show popup maybe maybe if the user has added let's say uh 10 this time right so if the user has to 10 added 10 to those we want to show a message in the model right so now we have some additional logic here and now we want to set the model open to True right I'm just imagining some model State the point here is very often you want to do multiple things so here we were only doing one thing but in practice very often you have additional logic when that event occurs and now the problem is of course that we we need access to the to-dos variable right but of course also we need access to the setter functions for the model right we have some model States on where and now this component suddenly is going to become very complex because we need to pass in a todos variable or todu prop and also a set additional Setter functions right so you can already sense that this is also not a great structure so what you want to do typically is you don't want to pass like raw Setter functions if there is an event happening in that component and you want to do something in that gate well you may want to just create a Handler function here that encompasses all the things you want to do so here we can for example just say handle uh handle add too and so we're going to put all of that logic that we were doing previously in here we're going to make this component much simpler Again by removing all of this from this component right this component doesn't need to know anything about models you want to keep your components dumb they shouldn't know about all sorts of different things right so we're going to pull it out of there and we're going to put all of that just here in one function very close actually to where we are dealing with the actual State here of the to-dos so now we have put all of that logic into one function here the handle add too I'm just naming it as in handling the particular event we can also call it handle submit but we can be a little bit more specific we can say handle add to-do and this is the function now that we want to pass down to the component right so here now this is what I want to pass down to the to-do form I will just call it handle add to-do for now so we only have to accept one prop handle add to-do and now the only thing I need to do is just call that in this component here this component right now doesn't need to know anything about how we're actually adding a to-do or other things we want to do like doing things with a model all of that has been extracted out of this component so this component is dumber now and that is actually a much better structure because you can see this component is much more easy to analyze to see what's going on and we have all of the state right here we have I have to do and all of the ways that I want to ways that I can update that state I can create a dedicated function for that here and then I can just pass that to any component that needs to invoke it right so we could also have one for handle edit to-do for example right we could have a function for that and maybe delete a to-do handle delete too right I'm actually clicking on that CR handle delete too right so now you have in one place the actual to-do State and also all the ways that you can update it and possibly other actions you want to do in that same update I would say that's a better structure and actually here we if we want to update this we do need to pass the uh content right so here we do need to pass the actual content of the to-do when you call that function but uh it works the exact same all right now here I'm calling it handle add to-do um so in terms of naming your props typically people do tend to stick to the convention that you have in Native HTML or jsx so if you have like a button element on the page if it has a click event you have on click right so if you want to hook into that and then possibly like handle click something like that handle and the name of the event is this is a pretty typical uh convention if you have an input you have something like on change right so click and change are like actual native events in the in the browser so if you have a custom component like add to-do form you can also view adding a to-do as like an event that happens in that component so you may actually want to expose a prop called on ADD too when you design the uh component you have to imagine other people will use this component what kind of prop name makes sense here well you can imagine that U I want to let the user of the component know that there is like an add to-do event happening here and if the user wants to tap into that they can pass a function and traditionally as we just the convention is that you call it handle add too for example right so then the prop name is actually on ADD too do so then when that event actually occurs that's also how you need to call that right so now this component doesn't need to know exactly what will happen when the form gets submitted it only knows that when that form gets submitted we know that's when we adding a to-do so that's when we need to actually call that function and we do need to pass in a to-do content how do we know that by the way we need to pass something in well if I actually type this with typescript like this so on ADD too is a function that takes in a string and doesn't return anything so now here I get a warning from tapescript hey you forgot something you need to uh you need to pass in to do content here right so here I can fix my mistake so I would say using typescript is also a best practice but now this is much cleaner I think this is a much cleaner uh structure where you have a component and you need to think about a component in isolation from the rest of the app right so you you have to think about what kind of prop do I want to expose here so I want to signal to the user of the component hey there's like an to to do events here that you can hook into and so when you want to do that and you actually do that you can just do it like that so it's in line with what you would expect from the typical HTML or jsx element and actually have another example here with with uh passing functions like that as a prop right so here for example we have this button component that we are reusing right so here we have button component and uh we have a bunch of Base Styles right so they all have similar Styles so here they all have similar Styles but if it's a secondary button then we have some additional Styles here right so here we can say secondary for these two and it will be a little bit different okay now say what we're using here we say button type is secondary for login and register so that works perfectly fine now here of course if I click on log in something else should happen than when I click on register right so here when we actually click on this button how would you implement that well there's a there's going to be a click event so here we would have on click now for the login button we may want to run a function called uh login I'm getting that from my authentication provider which uh I'm using kind here I'm a brand ambassador for kind it's a a paid sponsorship but I had a great time working with them so far so here I can use the kind hook and uh it will give me a login function so when I click on there it will invoke the login function okay right so if I click on there it will uh actually redirect me to a uh kind hosted login page I haven't set it up for this video so that's why I'm getting it getting that the point is I have now implemented this for the login feature now the problem here is that of course we're using the same component also for register here so if I click here on register now I will get the same result that's not what we want and the reason is actually very similar to what we had before which is we're making this component too complicated we're making it too specific to one particular use case to log in right imagine you were designing this component and you know you're going to use this component in multiple places for multiple use cases this is not how you would uh set it up right so instead you don't want to couple this too tightly to one particular use case instead you want to expose an event right so here it would be the click event just like we had the add too events here it would simply be the click event so you're telling the person that's going to use this component the developer that's going to use this component hey there's a click event that's going to happen in this components and you can hook into that and whatever you're going to pass as that function right on click you're going to pass some function we don't really care what it's going to be we're just going to invoke it when that click event occurs and so it's going to it's it's now a simpler it's more dumb this component it's not it's not complicated it's a simple one right we can remove all of this so now if you want to use that here I can now specify on click and here now I can specify function just like before what we're doing here I could write it up here um but here let's actually just do it in line that's perfectly fine as well for for this one I can call uh login and for this one I can call a register right so now this component is reusable and I can customize it through props right so here we we have now two different uh use cases for the same component this component is going to receive the whatever it's passed in as as the on click prop and it's just going to invoke that right here when it's actually clicked and it doesn't need to know anything about login or register it's dummer now it's more simple and the complexity has been lifted out of there essentially and um it's sitting up higher higher up right so now I would actually have to use the hook here right something like this so we get login register and then here we can pass that right so I think the main takeaway is try to keep your components especially lower in your component Tre or if they're re meant to be reusable like a button component don't make them very specific to one use case try to make it more General simpler and you can uh do that by exposing uh certain props so then when you actually use that component you can speci ify the particular use case right so that's how you can think about it and these components uh and in terms of naming the props well you can think about it as sort of like emitting an event right so here we we're sort of exposing the click event so when you actually use the component you can you can hook into that in this component we're emitting a more custom event an add too event so here we have on ADD too and if you want to do something well you can pass a function all right so it looks a bit complicated perhaps um now I would say check out my course if you really want to master that we practice a lot with it with other projects as well and we start from absolute scratch I cannot explain everything in one YouTube video I have to go through it pretty quickly here but uh in the course we uh I buil we built everything up from absolute scratch step by step so highly recommend you check that out if you really want to master react you can find a link in the description and by the way every time this component rerenders now for example if the to-do uh State changes it will render and therefore all of the statements inside this component function will run again right so rendering just means that all of the statements inside this function body run again and that means that this computation here is also done every rerender and that may be a bit of a performance concern right so here would be a use case for the use memo hook right so if you don't want to run this every time the component reenders you want to be a little bit more careful with that use memo so use memo here we just uh have a function in there and it should just return the result of the calculation right so here I will just return this the result and then what you get is the result in there which we can call the same way so let me remove this now in use memo it will not run every reender but sometimes it does need to be recalculated for example if the to-do is actually change right so we may have other state in here this a component May render for other reasons and we W and we wouldn't want to run this calculation if it's not necessary so in this case it's only necessary if the todu itself actually change so in this example it wouldn't be very useful but if this was if this component was re-rendering for some other reason now this calculation would not be done every render right so use memo is very often used for calculations like this very often like derived state right so something that we derive from existing state like this and we want to be a little bit careful with that so we can wrap it in a Ed memo very simple now as of recording this is still um useful to do but in the future that will be the re act compiler which will do something similar for you out of the box so in that case it may not be necessary anymore to use the used memo hook but for now the react compiler is not in react yet so uh we cannot use that yet so using use memo here I think would be uh I would say it's a best practice and by the way the way it works in react is that every time this component renders this function here is recreated right so every time this component renders a sort of like a new function a new function is created and assigned to this variable and that's what we then pass down here so just like what we saw previously with a calculation we can wrap that in a use memo you can do the same with functions if you don't want to recreate this every time we can we can wrap this in a use callback hook and let me import that and then we can specify when it should uh actually recreate it right so here we're saying it should be recreated when the to-dos actually change but other than that it can stay the same so then you should have a slide performance benefit I mean with small functions it's not a huge deal but the benefit of this is now what you can also do is here this form component here since um previously it was always receiving a new prop but if you wrap this in a user callback then it will not be a new function every time sometimes it's going to be the same function when it renders and what you can do is you can prevent this component from rendering in that case because the propit will receive will be the same and so in that case we can use react memo so this there another function here that I can import from react sometimes people will Rite it like react. memo um but we can essentially wrap the entire component in memo and actually assign it to a variable called add too form this will actually be the name of the fun of the component and that is also what we export at the bottom but basically now we have an additional optimization which is that if the props are the same this component will not render so it's cached and it's only possible because this function that we're passing is not going to be recreated every time right so now sometimes it's going to be the same and so we can prevent an unnecessary renderer right so these are essentially the use cases for use memo what we saw before if you have like an expensive calculation that you don't want to do every time it reenders you can wrap it in use memo also for objects for example right so if you do have some kind of object if you do have some kind of object here in the component function body it will be recreated every time if you don't want that you can actually put the object in here as well or an array not for State variables by the way those will not be those are not an issue but if you have an object or array and you're passing that as a prop to another component since they will be recreated every time well those components that receive those props will also render however if you would put those in a use memo right so objects or arrays or a calculation you can prevent those from being recreated or the calculations from being redone every time it renders and that's the benefit of used memo use callback is for functions it's very similar but just for functions as then the function here will not be needlessly recreate it every time so that's so that's already a small performance benefit but uh another benefit then is that if you pass an object or array or a function to another another component if you wrap that in react memo the props will stay the same because they've been cached either by use callback or use Memo by in case of an object or array use callback is for function so if the prop is cached it will it will be the same prop and so with react memo in that case you can prevent a rerender of that component right that's in a nutshell how use memo use callback and react memo work so for react memo you need to use that in conjunction with use callback or use memo that's a little bit complicated and I have separate videos on this as well when the react compiler comes um it can do similar things out of the box for you so you may not be so you may not need to use these anymore however as of recording react compiler is not in react yet so you may want to use some caching here as a performance benefit I would say it's a best practice for if you have expensive calculations make sure you use use memo and if you really have an expensive component that that's difficult to render or that has a lot of things going on you want to you want to prevent unnecessary reenders so you can wrap it in react memo which will prevent this component from rendering if the props are the same so you do need to make sure in that case that the props it receives so for example in this case a function that it will be that the function will not be recreated every time right so you need need to WP the function in use call back in that case or if it receives an object or array you need to W that in use memo right so a little bit complicated um so hopefully within the next few years we do not have to think about this anymore because react should be able to do that out of the box but for now this is something to keep in mind all right let's talk a little bit more about best practices with the Ed State hook or state management in general in react and we already saw uh an important one which is that for setting State you essentially have two options right so you can just set to some value but if the new value depends on some previous value it's probably better to prefer the updator function format so in this case for set to-dos when you add a new one for example you want to keep the previous ones right so here I want a new array but I want to keep the previous ones right so I will spread the previous ones like this and then I will add my new to-do here right and also for count right if you have if you have some kind of count States then technically we could do something like uh well you could actually specify a specific number right so then it would always become 10 right just just 10 but if it should depend on the previous one well technically you could do count plus one but now you depend on this variable right so we've seen this before what if you actually pass that to as a prop to some component you also need to pass the count variable in that case right so that's not really a good structure that we we actually don't even want to pass the set function but if you were to do that you would also have to pass the count variable but you may potentially run it to other issues as well for example in uh closures right for example here in a set timeout for example right so here count will not be it will not behave as you would expect for example right so count will only be set once right it will not it will not automatically increment because of closures it's a bit of a tricky concept I have separate videos on this but basically there are some pitfalls with this way of doing it however if you were doing it this way with the update a function it would work as you would expect right so as a best practice I would say this is the way this is the for this is the option you want to pick when your new state depends on the previous one also if you were doing like multiple Setter calls right after each other this will also not work as expected right so right so if if you have it's it's pretty rare but if you were doing something like that you also want to use this and then it would actually also work as expected uh react also batches State calls so and if you update it this way that would also not be a problem right so basically there are a bunch of issues with updating States like this where you depend on the previous state so as a best practice I would say try using the updat function when it depends on the previous state all right now sometimes for a particular state for booleans very often uh I see sometimes that people will immediately use a Boolean here right so for is loading it can be either true or false maybe we're fetching some data and we is loading true or false now you may also want to consider that in the future you may have other states for example if you're fetching data there could also be an error right so then then what are you going to do are you going to have another piece of states for is error or uh is success and in the success case we want to do something so now you have three pieces of state so instead what you may want to do is you want to have one piece of state and you want to just call it status right set status and maybe it's it in the beginning there is nothing going on we can just say idle and we can type this to tell typescript what options it could be right so we can have a type for this uh status could be idle loading error or the success case right so we can type this for type script as the status type so now the status State here needs to be one of those four strings this is a union type so it needs to be one of these four strings so if we're actually going to load some data we can set the status to uh loading and the benefit of typing this for typescript is if I make a mistake if I try setting this to a string that does not exist if I try setting this to a string that is not part of that uh type typescript will warn me and will tell me hey uh this is not a correct string you need to this is not a correct string it should be uh one of these four right so now I can fix my mistake maybe the data fetching gave us an error so we can set the status to error right so instead of immediately using a Boolean like is loading is error maybe you want to use a union type like this right I would say this is a slightly better practice I think it keeps the possible statuses confined to one piece of State all right so another uh best practice for uh State here let's say we have our to-dos here it's going to be an array right and initially may be an empty array or we may have some I to-dos in there so we may have a bunch of to-dos let's actually just take two okay so I have uh two to-dos in here right and that's how I'm keeping track of the and actually let's say we have three to-dos here so uh initially we may have like three to-dos and we may add more later but for now let's say we have three to-dos now very often if you have a list of something um and here we're actually not using that but let's say you can click on one of them on one of the items in the list to make it active or to select it right maybe I can click on this and instead of toggling the completed status we would see the details of that item right so maybe there were more details a description uh very common actually when you have a list of something you also have a way of selecting a particular item or make a particular item the active item that's also a piece of state that we need to keep track of and we cannot derive it from here so typically you also want to keep track of that so you can say something like selected to do and initially we don't have one so let's say it's null all right now the issue is that I sometimes see is that when I now click on let's say learn react here that means that the first to-do here needs to become the selected one how do you do that how would you update the state here so what some people will do is they will take the entire to-do and make that the selected to-do state right so they will invoke the setter function and they will set it literally to the entire to-do right so that would be the to-do with an ID of one and the text and the completed so they would put the entire object selected to-do right they would do something like this so essentially the selected to-do would now be the entire object let me actually write it like this so now the selected to-do is an object with the same information as the object here in the other state so far so good now this is a bad practice because what happens if you actually change the to-do right so what happens if I can actually uh change the text of this to-do instead of learn react I could change it to learn typescript right just something else I'm just writing it here but in practice you would you would have the setter function again and you would have some way of changing that right the point is I could change the content or structure even of this to-do the selected to-do which was meant to be the same is different right so this is not automatically updated when I update it here right so this is because I have two sources of truth right now and in programming it's very important that if it's possible that you have one source of Truth so here I'm trying to keep track of it I'm trying I'm trying to keep track of the same thing in two places and so when you update one of those two the other one is out of sync so then you have to remember that well if you change this one right here you also have to change this one right so technically it's possible but you can imagine you're going to you're going to forget about that or it's just very it's a very it's a very error prone structure to do it like this so that's not what you want to do you don't want to keep track of a selected item or an active item with by sort of duplicating the object or array like this instead you want to keep track of it by ID for example right so a better way would say select it to do ID selected to do ID and then so if I click on the first one to select it or to make it active well we are just going to keep track of its ID right and now um if I if this one gets changed if it's going to become learn typescript well that's not an issue because we're still pointing to that same object so whenever it it changes now well that's okay because we're pointing to it if we want the full object we can derive it right so now if I want to if I actually want to get the full object I can just take all the to-dos and I can find the to-do with the ID that is the same as that I have selected here as it is the same as what I have put in my selected to-do ID State and that's how I get the complete object and now whenever this changes if this changes into learn view well that's okay because I'm still pointing to that same object so if I need the selected complete object it will still find that same object and it has been updated but that's not an issue because I'm not trying to keep track of it in two or multiple places I only have one source of Truth with the same object still and whenever that changes well that's okay because I'm only keeping track of it by ID and if I want to complete object I can just find it by its ID and I will get the complete object with all the latest data in there right so seems a little bit complex perhaps but the point is often when you have like a list of something you want to have the ability to to select a particular item or make an particular item active do it by ID don't duplicate the object or array because it's a higher risk of getting out of sync all right so so far what we've done is well we have one important piece of data in this app here it's a small app and the one piece of data is a list of to-dos right we want to keep track of that we want to manipulate it add a to-do we want to delete ones so that's one piece of data to-dos that we want to keep track of that we want to be able to manipulate and when we actually change that array of to-dos we we want a rerender right so when we add a to-do we want to render that list so that we can actually view the new to-do right so we want to trigger a rerender right so the use State Hook is appropriate for that piece of data the to-do's data however there are some pieces of data in an app where you're better off not using the US state hook but actually putting putting it in the URL so a good example of this would actually be the uh selected color here for example for an e-commerce page and so let's say you're looking at some product here and they have multiple colors available let's say I pick a white color for the shirt you can see here it's actually it's actually being part of the URL here it's actually a so-called query parameter in that case you would not create US state for that right so you may think oh I'm going to say selected color and I'm going to make that white or something like that and so that's how you would maybe do it in the app but that's actually not what you want to do in that case instead you want to make it part of the URL not and then not do you state because then you would have and because then you would have that piece of data in two places you want to have one source of truth right so the URL would become the source of Truth just the one place and the benefit of that is you can copy this and you can share that URL with other people so then the other person person can copy can paste that URL and they can press enter and when they come to this page they will see the exact same view as what you were looking at because based on what's in the URL you're going to show the appropriate color so in this case you would show the white T-shirt image right so and and if you were clicking on the black color now that is part of the URL so you can copy this send it over to somebody else and I can ask them hey what do you think of this uh black T-shirt well they can simply copy that and paste that in your L and they would get the exact same UI also somebody can bookmark this and then so the URL when they when they come back on when they click on that bookmark later they will come back to the exact same uh view here meaning the T-shirt with the exact color that they were trying to get back to right I can also add the size here so you can see now it even is more so now I have the color and the size as part of the URL so if I want to save this for later I can just bookmark this and I can just come back to the exact same view of exact same combination because it's part of the URL and the app will take a look at the URL and make the right selection here instead of using use States right so that's not possible with using you state alone right here I cannot make the to-dos you know part of the URL it's not really uh appropriate but for some pieces of data like uh filters for example here the color and size or also like the page number if you have multiple Pages try making that a query program instead of using use State some some pieces of data are more appropriate for the URL and actually have a separate video on this because it's a bigger topic but I would consider it the best practice to make it part of the URL if you can and it's and it has added value for people that want to share it or bookmark it and there are some other use cases as well all right let's talk a little bit about use effect a very mysterious hook to many people but actually it's pretty straightforward so when you call that hook you need to specify two things you're going to specify the function that you want to run and secondly how often you want to run that function if it's if it's an empty array it just means that it will only run once when the component first mounts so this function right now only runs once now what you may want to do in here for example is you want to synchronize as a fancy word your data in your react app with something that is outside the react app for example local storage right so if I open up the def tools here if I can go to application here and here I have a an option here for local storage so I can store things in the users browser here in local storage so what I may want for example is that as the user adds more to-dos or deletes them or edits them that we persist that in local storage right that I can put the to-dos in here so then when the user comes back those to-dos that they added or they changed are persisted so it's the same as when they left right persisting data so so local storage is something outside my react app right so we have US state that's all in my react app but some things like local storage that's in the browser right the react team does not control logal storage or something like that right that's something as outside react so that is typically what you want to use to use effect hook for for things that are outside your react app and you want to synchronize them so here I may have my to-dos state with all sorts of to-dos and now I want to make sure it's the exact same in local storage right so you may want to do something like this so we put the to-dos in local storage but now this would only happen when we first Mount the component which is kind of useless so we want to do that whenever the to-dos gets changed right user may add it to- do or actually delete one or maybe we have an edit button or something like that so whenever it changes we want to we we then also want to update it in local storage right synchronize it with the data in local storage so here in the dependency array is the fancy word for this array we're going to add a variable now and whenever it and whenever it changes it will run that function here again right that is in a nutshell to use effect hook that's how it works and that's the purpose right so you have something that's outside re react and um you want to make sure that the data in those two places is the same right as a beginner in react for example you also learn fetching data typically with use effect so basically you can view it as you have some data in a database somewhere and that is outside your react app so with use effect we can make sure the data outside the react app comes into our react app here we can put it in state and so we can synchronize our client site app react app here with the server s side all right so there are some best practices I would say with use effect as well so you want to make sure that each use effect instance takes care of one uh purpose essentially so what you don't want to do is do multiple things in the same use effect so for example uh you may want to do something else in the app as well which is maybe you want to listen for when the user presses the Escape key on their keyboard and maybe you want to do something for example if they have selected uh some to do and they press Escape we want to delete it right so you want to set up something um in the in the Dom or the window object or the Dom that is actually also something that is outside our react app right the Dom the window that's coming from the browser that's not coming from our react app or something like that right so here we may also want to use use effect for that and so that's what we have here essentially but now we have put this in the same use effect as where we are as where we're trying to update local storage and because we added the local storage here remember this depends on this to-dos variable and so we added we added that here here to the dependency array and so whenever to-dos change use fact this use effect function will run and that means that right now whenever to-dos change we are also adding this event listener to the document even though this has nothing to do with the to-dos right so now we're going to keep adding whenever we change something here if I delete one right the to-dos change and since the to-dos have changed here it's going to run this function again and so indeed it will update local storage with the with the latest to-dos which is correct but then here going to Define this function and then we're actually going to attach that as an event listener again to the document which is completely unnecessary and you can imagine that this is not what we want at all right so instead what you want to do is simply just invoke another one right we can just create another use effect here and so now they are nicely separated into their own use effect calls right so you want to have one for each use effect all right let's talk about fetching data in use effect this is what you're going to learn as a junior react developer you're going to learn about data fetching with use effect so is it a best practice probably not and I want to show you why you typically want to do you you typically want to do data fetching in a different way but let me show you why that's the case actually in the remote Dev project from the course we actually have a great example of this um basically this project you can click here and it will show you a new job post I'm actually using the same picture in the background for all of them but we are actually seeing a new one when I click here so you can see this one is front end react engineer that is indeed the title here and this one is frontend developer and that is indeed what we see here right so then have we have asent Tech as the company name for this one right so when I click on any of these in the list here we are making a fetch call to get all of the details of that particular job post right so these are all job openings so this remote def website is for uh it's actually about remote developer job so if you're looking for a remote developer job you could find one here right so then if you click on any of these in the list we're actually fetching the relevant details for that particular one okay now how are we doing that well um we are using user effect for that right so that we have some data on the server side and now we want to bring that into our react app right so that's a that's a fine use case for use effect so how are we doing that so we Define a function in here actually fetch job item we want to keep track of the loading state so very simple we just set this loading to true and then we make an actual fetch call right so I have some base API URL basically my c.com uh domain and then we need to know the specific one that we want to get the data for that so they have certain ID that we put in the URL that's a best practice as we talked about right because now I can share this with somebody else hey what do you think about this job post and they will copy and open that up in their browser and then they can see the exact same job post as we were looking at right um we get that we're keeping track of that here in the context uh API we talk all about that in a course step by step but uh basically we get some active ID from the URL so that's how we get the so that's the complete URL so we will get some response and then we actually get the data okay and that's what we actually set in state right so initially it's going to be null but when we actually fetch data we actually store that in state and then we set is loading to false right we do that's just defining the function we do need to actually call it here now here the logic here depends on the active ID so whenever this changes in the URL uh that's basically how we're doing it so when I click on any of these we're changing it in the URL and so this active ID will change be will because of that and since it's part of the dependency array we're going to make the fetch call again so that we can update the state with the relevant job item right that's basically how it works in a nutshell don't worry if you're a little bit confused the point here is I'm doing data fetching here in use effect basically the uh the traditional way or the way that you learn it when you first start getting into react now what is the problem with this well let me show you this in a network tab so if I click on the first one in the list here you can see there is indeed that fetch call right if I now click on the second one you can see there is a fetch call again right actually going to the server and coming back again but what happens now if I click on the first one again if I click on the first one again you can see there's another fetch call but that is kind of strange because we just made that fetch call right here why do we need to make another fetch call for the data that we already received before it would be easier if we could just reuse that same uh data right this is not efficient what if I click on the second one that I already clicked on before I just clicked on that and now we're making another fetch call for the same data that that I already fetched like 10 seconds ago right so as you can see as I keep clicking on the first and second one there is no caching here right it has to make it's making a new network call every time I click there it's not really efficient but that is essentially what happens if you do it like this right well a better alternative would be to use for example react query which is what we're using in the course so actually we create a custom hook here you don't really need to understand how all of the custom hook stuff works but basically instead of use effect we're going to use a hook from react query called use Query and actually we put that in our own custom hook but there's a special hook but the hook that you get from react query is use Query and basically it allows you many it gives you many many benefits and we cannot discuss it in depth here it looks a bit complicated but the point is I'm not using use effect anymore now I'm using that use Query Hook from react query if I now click on the first one we are making a network call here right because the first time well you you need to get the data the first time okay and now I'm going to click on the second one in the list and again it's the first time here now that I'm clicking on it so it gets it makes an actual Network call but now what happens if I click on the first one again if I click now you can see it instantly shows me the job item that we got the first time without making a new fetch call and if I now click on the second one again you can see it updates almost instantly here it does not make a new network call because it can see oh you want to get the data for this particular job item id well we we already fetched that like 30 seconds ago so we can simply reuse the response from that particular fetch call and therefore we do not have to make a new network call right so you can see how fast this is right when you add caching to your data fetching that is a very substantial Improvement right so if I the third one I didn't click on it before so you it has to get some data and the fourth one as well right so the initial time it has to actually get the data but now if I click on the third one you can see and fourth one you can see it's instant and these are all instant now because the data has been cached and there are many other benefits to using a thirdparty library instead of doing data fetching yourself and use effect you probably want to use a thirdparty library that has taken care of a lot of issues that come with doing data fetching in use effect yourself now in the course we also talk about nextjs nextjs also has a certain way of doing data fetching it also comes with caching Solutions out of the box so in that case you don't even need react query it's so in nextjs you don't even need react queries because it has Cashing Out of the Box uh but there are some caveats so if you really want to know about these things I highly recommend you go through my react and nextjs course we start from absolute scratch we go through things step by step so if some things here seem a little bit uh fast for you that's okay that's totally normal actually because it looks kind of complicated here I understand but once you go through the course we we do everything step by step so I highly recommend you check it out right so as a best practice I would say if you're creating a react V app probably you want to use a thirdparty solution like react query or S SWR by forsel or you want to use nextjs which of course has many other benefits but it also has caching for data fetching out of the box if you don't really follow best practices what I see especially with Junior react developers is you get very messy big component so usually if you have a big messy component and it's difficult to read what's going on it's typically a code smell in my view so let me just show you what happens in that case right so let's say we have some to-do list component just very similar to this I I changed this component a little bit to show you what happens without using best practices so we have some State here some use effects and you can see that's already kind of strange what's going on here okay so it's local storage okay but uh we have a lot of markup here so here for example if there are not to do yet we may want to show we may want to show like a an empty state right so if I delete everything here um we we want to show something like this right so that's for that part and then here we have the actual list so we take all to-dos and we create an Li for each one you can see there's a lot of markup here so there's a bunch of markup here delete button uh let's see and then here at the bottom we have two more buttons reset to-dos and also here for marking all the to-dos as completed right so here I'm breaking several rules so let's see what we can improve here so first of all as we talked about in the beginning don't be afraid to create components even if you're never reusing them components themselves they clean up a lot of code right so if you have a bunch of markup see if you can divide it up in smaller component so for example this part here I can easily create a separate component for this I could technically do it at the bottom here in the same file right which is fine with me if I'm only if I'm only going to use the component for this in this one file I think that makes sense I could also create a separate file for this we can call it start screen or something like that I have a react code snippet extension so I can quickly create a component here uh actually I will just uh copy this paragraph only and that's what I'm that's what I'm going to return here I'll delete this and now I can use this instead of all this markup we now will just have one clean uh component here essentially we can just say uh now I think this looks this little piece here looks cleaner to me and actually we are using a turnery here I may want to use a uh an logical end operator because then you don't have to write or no so I think this looks even cleaner and now you can see it's also much easier to see what what the markup was for right because with the name of the component you're essentially telling what this markup is about right so it's just a very simple paragraph but we have kind of labeled this markup now uh so not only does it take up less space it has also been labeled right so let's see what else we can do here so here we have a bunch of markup here for this list where we actually map over the to-dos and actually it makes sense I think that you have a to-do item which is going to be for the entire Li right so what I would do is I would create a file to- do item in which I will create a component called to-do item so then here I would copy all of this the entire Li here I will copy that and just paste that in here I can remove all of this and I can just use my to-do item component right so that's much cleaner now here we do need to pass the all the information about this to-do so we can actually just say to-do is the is too I just pass it as a prop it's okay okay then I could type this out but I will keep it a bit simple here and now you can see I've cleaned up that entire list by just creating a component for that markup essentially for that Li that's all I did here actually we do need to make sure the key uh goes and sit here for this uh and actually I think we can even write it without the return keywords on the same line yeah okay actually it's insert and actually pretty your inserts parenthesis from a but you can see this is now much cleaner right and now of course right I'm getting a red quickly line here because too has not been properly uh typed here let me quickly type this right so this is an array but but typescript will try to infer what kind of array this is going to be it doesn't know if it's going to be an array of strings or an array of booleans and actually it's going to be an array of objects right with each object being a to-do right so here we created a to-do uh type in the in the course project we can tell typescript hey it's going to be an array of to-dos and so then uh we should get of the red squiggly line here yeah all right so then basically we could type this as well but one other thing we can also do here is uh let's see but because this is still quite messy right so there's a bunch of stuff going on here well one thing we could do is well you can see there is another sort of like an independent piece here which is a delete button delete button is semantically also kind of its own thing in the course we actually create a separate component for that as well we're actually using the context API that's where we're getting the lead to-do function for so this component is what we want to use instead of all this markup here we can start cleaning up this this component as well by just creating even smaller uh more specific component right so here um I think that already looks better and uh there is another thing here this still looks messy right so here we're trying to when you get it to do we may for example want to uppercase only the first character of the first word not all of the words only the first word you cannot do that with CSS CSS will uppercase every word so here we have a lot of like like JavaScript magic here to make that work which is kind of uh well which is not really great syntax um we can remove the comments here right so here we created a delete button which removes a lot of markup here but also labels what that markup was for so it it's easier for us to interpret what's going on and now we want to do something similar for this piece here but this is not markup this is more like JavaScript logic so is there maybe a way that we can simplify this or like label it and maybe also so of course reuse it right because now when I create a delete button component if I need the same mark up somewhere else I don't have to duplicate a bunch of markup I can just use delete button the delete button component right so the way I think about reusability is if you want to reuse a bunch of markup right create a component out of it if you want to reuse or clean up JavaScript logic so not markup but Logic for example here for upper casing the first character you can try creating a utility function right so here I like to have a utils or helpers file and here we can create a function capitalize first letter right so this is just a simple JavaScript function and you can pass in some string and it will just take that string and uppc case the first part the first character right so now I can use that function instead of all of that I can just use that function here and then pass the actual to-do text the content right so now you can see this looks this it looks much better but I have also labeled that logic I can see what that logic means right it capitalizes the first letter right so previously I had to parse myself what does this actually do I have to actually sort of analyze it myself and get to work to see what's going on here but now I don't need to parse that actual logic I have sort of labeled it by putting it in a separate function and now I also get to reuse it in other places in my app right so here I'm only doing it in this in the to-do item but maybe in some other place I also want to do the same logic so now I have the same function that I can use elsewhere right so not only is it cleaner in terms it's it looks cleaner but it's also more reusable at logic okay so let's say we're satisfied here let's go back to this to-do list uh component a little bit more so here we still have these two buttons right so very common for a junior re developers is they duplicate a lot so here we can see there's a bunch of markup again it's a button with the exact same styling that's duplicated well we can create a component called uh button simply right I can just create button and replace all of this also all of this I can replace all of this I do need to import it here you can see I have now repl all of that markup with this button component all of the markup has now been moved here and we're only writing it once instead of twice here right so all of the styling is in here we've seen this button component before now if you have a reusable component we can still customize it in a particular instance right so the text in there we want that to be different we can do that like this with the children uh prop and of course if you click on this button something else should happen then with the other button so here we still have um a way of doing that because we can just pass in what we want to do here because this button will accept any function here for on click and it will just run that when you when you actually click the button right so here we would want to do something like uh set Tod do to an MC array and here this should be um a little bit more uh complex perhaps but all the to-dos should become marked as completed and actually we could create a separate function for this handle click and actually we could create a separate function from this handle Mark all as completed and actually to be consistent we could also create a separate function for this handle reset or something like that we talk much more about this in the course but now you can see I mean this function still takes up quite a bit of space so I would probably go for so we can talk more about that but this is already much better to analyze it's much easier to understand what's going on than before it looks much cleaner and now if you want to use this button in other places in your app in other components we have a a reusable component ready to go okay so that is essentially reusing markup right so if you want to reuse markup try creating a react component if you want to reuse uh logic right so here what we did with capitalize first letter try creating a uh utility function or helper function if you want to reuse logic that has a react hook in it we also want to create a utility function but because it has a react hook in it we don't call it a utility function we call it a custom hook so that me also an example that because this is still a little bit tricky to understand so what we essentially have here is we we are trying to keep track of the to-dos in state you state but also whenever it changes we want to update that in local storage so we want to persist the data in local storage so I know what's going on here because I I took a couple seconds to really parse what's going on here but it would be nice if we can also uh do something with this and we can actually so we can create a utility function essentially but because there's going to be use State and use effect effect in there basically react hooks in there it's going to be like a special utility function that we also pre-end with uh use because it's using react hooks in there and it has certain and therefore it's bound to the rules of react Hooks and we can also get rid of this and replace all of this with with just this one line here use local storage and it will still give us exactly what we want which is to-dos and set to-dos but now we have replaced all of that code with just this one custom hook and so now it looks much cleaner but also we know almost instantly what's going on here because the name of the custom hook already gives me that information right we have labeled that logic by using a custom hook and also it's more reusable now because if we have other pieces of data that we want to persist in local storage I can use the same hook and I can Define the key under which I want to store that data in local storage right so now this is also reusable right it's more more it's more General now than just todos it's it accepts any key now I'm ignoring the typescript here in the course we talk about uh this much more and actually what I'm doing now here with local storage I'm only setting the items right I'm not when we're loading it we're not getting the items back from local storage you can actually do that immediately here in use State as well with a function actually so you can actually also just do here we're setting the item in local storage here we're getting the item if you do you can actually pass a function to use state it means it will only do it once so you initially you will get the items from local storage when the component where you use the custom hook first mounts right so when it first mounts we're getting it but but that's not really important here the point here is we can even clean up code with hooks by creating a custom hook and then it's also reusable right so one more time because I think it's really important just as a general rule I think it's it's good to uh know as a best practice I think that if you want to reuse Market up try creating a react component and if you want to reuse uh logic try creating a utility function and if you want to reuse logic with a react hook in there try creating a custom hook right custom hook sounds so difficult but it's actually just like a utility function with react hooks in there but that is basically it you can see this component now I would say uh looks much better there are some typescript issues here but we don't have the time to take care of that right now but basically these were I would say the most important best practices in react if you want to master all of them check out my react and nextjs course I hope this video helped you out I'm Wesley by the way I'm a brand ambassador for kind which is a paid sponsorship but I had a great time working with them check them out as well in any case thank you for watching hope to see you my course have a nice day bye