Refactoring a React component - Design Patterns

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
what's up guys terus cin here in this video we're talking about design patterns and general best practices in react and the way that we're going to do this is we're going to take a component and refactor it using those patterns and best practices and see just how better off we are all right cool so this is the component that we're working with for this video it's called the user products page and as the name implies this is the page that we get to see the products of a specific user and although this isn't such a big component it's only 67 lines of code there's enough that we can improve to actually see the value of using design patterns and best practices in react so the first thing that we have here at the top is we have an interface that defines our filters currently we only have this created ad property of type date then we have the actual props of the component we only have user ID then here in the state we have a piece of State for the filters right it only has the created at we're going to use this to be able to filter our products that we see on the screen then we have a state for the model is the model open or not and then here we have a fetch that is done through react query and this one is specifically fetching the user using the user ID from the props right we're going to get to this in just a moment but for now let's move on then here we have another fetch this one is fetching the user products it's using the user ID and the filters from the state to actually fetch the products with those filters and then display it through this products property right here then we have a handle button click function which will basically toggle the model then we have here this use effect which is pretty common in a lot of applications where you want to track a page view event right we are on the user products page so we want to track a page view of ID user products page and then send some optional data like the user ID to then later attribute this to the correct user then we have this is loading variable which is defined as either is loading user or is loading products these come directly from react query right here and then if loading is true we return a div that says loading otherwise we return this jxx we have one header tag for the US username we have a button to open the model if the model's open we're rendering this user products filters component we're passing the set filters from the state as the onchange right here and then we're rendering the products right here if we have any products great so now we have our component we understand it let's actually improve this and the first thing that I want to look at is this model right here specifically this piece of State this function that updates the Sate here and then all of this jsx that renders the model and the actual contents of the model the thing is whenever you have state in your react application you always want to ask yourself does this state actually need to be here or can it be moved somewhere else somewhere else being either in the parent right maybe you have another component like this one that needs this piece of state so it would go in the parent or can you move this piece of State a little further down to not have the entire user products page reender whenever is modal open changes right because every time that we change this value through this function here we're causing a whole reender of this entire user products page component so if we can avoid this then it's a better thing to do so in our case right here with is model open if we look at where this is actually used it's only used here in this function and then in this jsx right here we have the button to open the model and then we actually render the model contents what I would do is I would put all of this in its own separate component to follow the single responsibility principle that is a design pattern in react which essentially means that we can have one component that only handles this button right here along with the filters and have it encapsulated away from this component this is also as I've said going to remove this state here which is going to prevent this component from rendering whenever it changes so let's actually do that let's come here and create a new file I'm going to call this one user products filters button ttsx this is going to be as we said a custom component so I'm going to do r jsfc p for props user product filters button and then for now we're just going to give this a div we're going to save this and then what I want to do is take all of this jsx right here and then just copy this and put this inside of this diff right here then we need to import user products filters so we'll do that and then we need here as you can see if I save we need is model open right so we're going to come back here to our main component and we're going to take his model open and we're going to put it in this component instead and then import you state from react and then we need two things we need this handle button click function which we can get right here so this is no longer needed in this component so I'll take this one and then I'm going to put this here and then we need the set filters function which comes from this filter state right here now you always want to ask yourself just like we did about this piece of state where does it belong you also want to ask yourself does this filter state belong here or can we also move it in this component and the thing is if you look at at where filters is being used it's used here with this request we're fetching the user products and we're passing the filters to this function so as long as this function lives in this component because it depends on filters filters also has to come with it so we're not going to move this function inside of this component because it doesn't make sense so this means that filters has to remain in this component so then what we need to do is we need to pass this set filters function to this component so that it can then pass it to this user products filters so the first thing that we need to do is we need to create here a props we can do onchange and let co-pilot be very helpful and complete it for us I'm going to import this filters right here save this and then we're going to do it here on change and then pass here on change save this with the right wording and now what we've done is we had this component take the onchange and then pass it further along here some people might say this is prop drilling but honestly if you think about it it's only two layers deep so I wouldn't even consider this prop Drilling and realistically in a react application you can't completely ignore or get rid of prop drilling so this is perfectly fine then we can come here to our main component we can go down here where we removed our jsx and we can just put user products filters page button and then on change we pass it the set filters and now we have everything that we had it before but now this is encapsulated in its own component the naming of this component makes it very clear as to what this component actually does and we're following the single responsibility principle designed pattern in react which is a great thing then the next thing that I want to look at is this fetch right here that is fetching the user and specifically I want to look at these two properties right here so we have GC time and stel time and they're both an hour these are properties that will tell react query to cat this data for an hour and not hit the back end whenever we call fetch user and instead return the cash response so the fact that we have this here and the fact that this is the dependent on the user ID we can also reasonably assume that you might use this in other places as well maybe there's another page that needs to fetch another user and you want to use the same piece of code right here and when you find yourself in that situation that is a prime candidate to extract this into a custom hook so what we can do we can come here we can create a new file I'm going to call this one use fetch user. TS and I'm going to do export const use fetch user give this for now a user ID because we'll need the user ID that is going to be number and then for now it's not going to return anything because we haven't implemented the function yet then I'm going to come back here and I'm literally going to take all of this copy this and then paste it inside of this hook and then save then we need to import fetch user so we'll do that we also need to import use Query so we'll also do that and then instead of destructuring the variables here like we have we're instead going to return and get query and then we're going to return the query so that the parent the caller of this hook can actually do the destructuring and access all of the properties that they need all right so this means that if we go here we can replace all of this piece of code with our new hook use fetch user and then all we have to do is provideed user ID and then we are done we've essentially achieved the same thing but this time using a custom hook which has the benefits that if we ever need to change these values here GC time or St time we can do it here and we can also have this apply to any other place that we have used this us fetcher hook and this is a really great design pattern in react that's called custom hooks whenever you find yourself in a situation where you have repeated code like this that you might want to use in different places you always want to extract it into a custom hook you want to do all of the logic inside and then use that custom hook inste set it's much scalable it's much better and as you build react applications you're going to see that this is a better alternative cool now the last thing that I want to look at in this video and this is also very important so make sure to stick around it's this piece of code right here now this what we're going to do isn't exactly a design pattern but it's something that you always want to do in your react applications because it's going to save you a lot of bucks if you look here at this piece of code we have an effect that on Mount and whenever this user ID changes will track a page event the problem with this is that there's nothing that can guarantee me that I'm actually calling the correct key here for the page event and that I'm passing all of the correct information I can have a typo here I can do W and there's no error that I'm going to have I can also put here a typo again have a different letter and also there's no error that I'm going to have and if I do this if I manage to ship this into production I'm never going to track these actual page events for this specific page because the keys here are wrong if I forget to add a data for example I might not send the required data to properly attribute this to the correct user in the analytics provider right so we want to avoid this and the way that we're we're going to avoid this is by creating our own custom layer in between and with the power of typescript we're going to enforce that we always call this correctly and that we always call a correct page ID with the correct data that belongs to that specific page ID so what I'm going to do I'm going to come here and create a new file and this is also going to be a custom hook as you see in react react was built to be used with custom hook so it's really really important I'm going to call this one use page view event actually use track page view it's going to be simpler it's a little bit more descriptive do this and then inside of this file I'm going to do export const use track page view and for now I'm just going to make it equal not take anything and we're going to handle the implementation in just a moment because first we want to create the types for these specific events that we can actually send so I'm going to come here and make some new lines at the top and first we're going to start with this page event right here this user products page so I'm going to do interface us user products page and I'm going to call this event this one is going to have page ID that's going to be user products page and then the data is going to be user ID number I'm going to save this and we have it and now although we don't have another page this is the only page that we have what I want to do is create a new page just so that you get to see how this would look like if we had multiple page pages so I'm going to do interface product page let's do that and then here page ID let's see can co-pilot do it product page perfect and then data co-pilot product ID number right so we have two pages the user products page event and then this one and also this one should be event as well save this and we're good now what we can do is we can Define our actual page event so we can do type page event equals either user products page event or product page event so in the future if you ever have other Pages you can define a new interface and just add it here and everything is going to work accordingly you can Define your data specifically for this page ID and now here in this used track page view custom hook we can just do event page event and then optionally because we are going to take this entire code including the use effect and these dependencies here we are going to create another parameter call it depths and then this one is going to be unknown and it's going to be an array of unknown and and we are going to save this like so then we're going to come back here to our main component and we're going to take all of this remove this and then put it inside of this component right here we are going to import use effect we are going to import Track event and then here instead of user ID we're going to pass it depths then in this track event we can guarantee we'll actually have to guarantee at least once that this is correct right so this is on us so we're guaranteeing that page view is correct it's the correct key of the event that we want to send and then instead of all of this all that we have to do is just pass event and we can save we've done the same thing but now we've guaranteed that this event can only ever be one of these two user products page event or product page event or in the future any other page event that we want to add to our application then coming back to our main component we can just import this hook and use it so we can do use Page Track page view and then we just need to give this the event so that's going to have page ID and again intellisense is going to know directly we can either have product page or user products page we'll just do that and then here the data is going to be user ID and then we can save and what is the error here expected two arguments but got one right we also need to provide it the dependencies so that's going to be user ID in an array because this is going to be an array so just with this hook we can now put this on any page that we have and we can give it the correct page ID and this is now properly typed so we prevent ourselves from actually making any mistakes if I remove this data here it's going to complain to me that I don't have the correct data or if instead I provide it but I provide something else a string for example it's also going to complain that user ID expects a number and not a string right so we have complete type safety and we've now prevented ourselves from ever shipping any code in production that is not going to work with our analytics provider now although this isn't your typical design pattern in react it's always a good idea to do it this way and to think about it in this way especially if you're using typescript in your react application you always want to have proper types for everything that you do in your components and you always want to try to create a reusable layer between the thing that you're actually calling and the caller of set thing doing it this way you can always guarantee that the thing is going to be called in the way that you can predict and you can prevent shipping dangerous bugs in your production applications which is always a thing that you want to try to avoid so there you go that's it for this video guys if you enjoy this if you learned anything I would really appreciate a subscribe you can click here to do it you can also click here to watch a different video of mine which I'm sure that is super super awesome because YouTube is the one recommending it to you and with that being said as always my name has been D causin this is causin Solutions thank you so much for watching and I will see you all in the next video chaa
Info
Channel: Cosden Solutions
Views: 68,324
Rating: undefined out of 5
Keywords: react tutorial, react crash course, react developer, learn react, react hook, react hooks, react hooks tutorial, programming tutorial, react hooks explained, computer science, tutorial for beginners, react component, learn programming, web development, frontend development, coding for beginners, simple code, easy programming, react, react native
Id: PisA-OPisUY
Channel Id: undefined
Length: 15min 18sec (918 seconds)
Published: Mon Dec 04 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.