Get the latest AI workflows to boost your productivity and business performance, delivered weekly by expert consultants. Enjoy step-by-step guides, weekly Q&A sessions, and full access to our AI workflow archive.
Summary
In this video by Cosden Solutions, the creator dives into one of the most crucial design patterns for React developers. Emphasizing the importance of structuring and architecting React applications, the video unravels the process of transforming messy, inefficient code into organized, efficient, and reusable components. By highlighting the significance of following design patterns, particularly splitting large components into smaller, manageable parts, the presentation guides viewers on maintaining clean and error-free code in React projects. Additionally, the creator offers a free document on other vital design patterns available through a newsletter signup.
Highlights
Learn the most important design pattern for clean React code! 🚀
Transform messy code into organized and efficient components. 🔄
Access a free document with 10 essential design patterns. 📄
Subscribe to 'Import React' newsletter for ongoing tips! 📨
Never write bad React code again with these insights! 💼
Key Takeaways
Understand and apply key design patterns to write clean React code. 🧹
Break down large components into smaller, reusable parts. 🔍
Utilize custom hooks for shared functionalities across components. 🎣
Follow the single responsibility principle for cleaner code. 📏
Subscribe to the free newsletter for more design patterns! 📬
Overview
In a captivating video by Cosden Solutions, viewers are introduced to a vital design pattern in React development. This pattern is essential for developers aiming to maintain a clean and efficient codebase. By focusing on breaking down large components into smaller, focused ones, the video makes a strong case for transforming the development process from chaotic to organized.
Darius Cosden walks us through the method of refactoring existing React code that violates best practices. He emphasizes the significance of using custom hooks for shared functionalities and following the single responsibility principle for clarity and maintainability. Through practical examples, developers can see firsthand how to enhance their React applications' structure.
In addition to the video tutorial, Darius offers a generous resource: a free document detailing ten other critical design patterns. Viewers can access this invaluable guide by subscribing to the 'Import React' newsletter. With these tools and insights, developers are equipped to write top-notch, error-free React code that adheres to best practices.
Chapters
00:00 - 00:30: Introduction and Importance of Design Pattern The chapter titled 'Introduction and Importance of Design Pattern' emphasizes the significance of understanding specific design patterns in software development, particularly for React applications. The speaker expresses the profound impact that mastering these patterns can have, suggesting it can virtually eliminate the production of poor code. The chapter will focus primarily on one crucial design pattern essential for any React developer, while also mentioning that there is a list of ten additional important patterns to be aware of.
00:30 - 01:00: Free Design Pattern Document The chapter discusses a free design pattern document that is offered to readers. This document contains text and code examples of 10 different design patterns that are essential for React developers. It is completely free and can be obtained by joining the 'Import React' newsletter. Once subscribed, the document is sent directly to the subscriber's inbox.
01:00 - 01:30: Overview of Design Pattern This chapter discusses a unique design pattern that doesn't have a specific name. It is a blend of smaller design patterns, ultimately aimed at teaching the proper way to architect applications. The focus is on how to create and structure components, subcomponents, custom hooks, and functions effectively. The chapter serves as a comprehensive guide to improving application architecture by integrating various design principles.
01:30 - 03:00: Understanding Bad Code in React This chapter focuses on understanding what constitutes bad code in a React project and how to improve it. It begins by emphasizing the importance of setting up and architecting different pieces of a React project efficiently and following the best practices in code and React. A significant part of learning involves examining examples of code that violate design patterns, don't adhere to best practices, and are generally messy and hard to understand. The chapter aims to help learners identify why certain code is considered bad and how to recognize such issues.
03:00 - 03:30: Refactoring the App Component - Part 1 The chapter discusses the process of refactoring the App component in a React project. The emphasis is on improving the code's efficiency, adherence to best practices, and enhancing its understandability for developers. It begins by addressing common issues in typical React code that might be encountered in various projects.
03:30 - 04:30: Refactoring the App Component - Part 2 In this chapter titled 'Refactoring the App Component - Part 2', the focus is on the challenge of managing a component with a large number of state variables and hooks that are unrelated to each other. The speaker refers to this as a 'wall of state,' highlighting the complexity and lack of cohesion within the component. Examples of state variables mentioned include count, name, email visibility, item selection status, and dark mode status. The chapter critiques the use of multiple useEffect hooks that perform actions such as interacting with local storage and setting the document title, which further complicates the component's structure. The chapter underscores the need for refactoring to improve organization and manageability of the component.
04:30 - 05:30: Creating Custom Hooks The chapter discusses the unnecessary use of certain functions within code, like an increment function that isn't needed because of the existing set count function. It highlights the complexity and confusion that can arise from having too many scattered functions, especially for new developers. The chapter emphasizes simplifying code to make it more accessible and less intimidating for newcomers.
05:30 - 06:30: Optimizing Custom Hooks The chapter 'Optimizing Custom Hooks' discusses common issues in React projects where code is functional but not efficient. It highlights a lack of adherence to best practices in many projects, especially ones you might encounter in different work environments. This often results from developers not fundamentally understanding React's intended design.
06:30 - 07:30: Extracting JSX into Components The chapter titled 'Extracting JSX into Components' discusses refactoring a piece of code to improve its structure and design in a React application. It highlights the need for breaking down a large component into smaller, more manageable components. The process involves dissecting a large block of state within the app component, which is initially cluttered. The goal is to learn and apply design patterns to better architect React applications, ensuring each component has a clear and manageable function.
07:30 - 09:30: Handling User Form Component The chapter titled 'Handling User Form Component' discusses the core issues related to the main entry point of the application. It emphasizes that the main component should ideally perform just one key function: integrating various fragments of the application that are spread throughout different folders and the code base. However, the current state of the component contradicts this by maintaining the state and managing functions related to state manipulation, as well as implementing various functionalities such as user account and names. This concentration of responsibilities in a single component contravenes the single responsibility principle, which is a crucial design concept.
09:30 - 11:00: Improving User Form Component The chapter focuses on a pattern in React where each component or function should ideally perform a single task. If it needs to do more, it should delegate tasks to another component or function. The discussion involves breaking down a user interface into more manageable parts, like separating a counter into its own component or hook, and organizing user-related form items (name, email, etc.) separately. This method aims to maintain a clean and efficient code structure. Additionally, there's consideration for handling state management, such as implementing a dark mode feature.
11:00 - 13:00: Dealing with Form State and Sub-Components The chapter discusses the organization of state management in applications, particularly focusing on separating concerns within the code. It emphasizes the importance of distinguishing different sections of the application state and placing them into separate components for better manageability. The example given highlights the 'count' state, which is moved into its own component to enable reusability across different parts of the application, demonstrating how functionality such as incrementing or decrementing the count can be shared across components that require it.
13:00 - 15:00: Handling Dark Mode Toggle In the chapter titled 'Handling Dark Mode Toggle,' the discussion focuses on updating the count through a separate hook. The process starts by navigating to the sidebar and creating a new folder named 'hooks' in the 'SRC' directory. A new file, 'useCount,' is created but later corrected from a '.tsx' to a '.ts' file type. The chapter outlines the steps to export a function named 'useCount,' which, for the time being, does not take any arguments.
15:00 - 17:30: Conclusion and Final Remarks The chapter focuses on the final steps and concluding remarks of a project that involves setting up state management in an application using React. The main aspects discussed include managing the 'count' state variable, utilizing 'useState' and 'useEffect' hooks, and ensuring that the 'count' persists using local storage. The chapter concludes by integrating function components that allow incrementing and decrementing of the count.
17:30 - 19:00: Free Resource and Call to Action This chapter discusses the use of custom hooks in React. It emphasizes the importance of removing functionality that's no longer required and confirms the absence of errors in the component other than an unresolved JSX issue, which will be addressed later. Custom hooks are highlighted as a React design pattern beneficial for reusing functionality across multiple components.
The Most Important Design Pattern in React Transcription
00:00 - 00:30 This is, I think, going to be one of the
most important videos that I've ever made on this channel. Because if you understand this
design pattern that I'm about to teach you, and you really get it, and you apply it to your
own projects, I'm telling you that it's going to be virtually impossible for you to write bad code
in your React applications. It's that important. But there's actually more. So in this video, I'm
only going to be showing you one design pattern, the most important one, the one that you
have to know as a React developer. But I've also gone ahead and created a list of 10 more
design patterns that are equally as important,
00:30 - 01:00 just maybe a little bit smaller, in a document
that I'm giving to you completely for free. This document will have text and code examples of 10
different design patterns on top of the existing one that I'm showing in this video, that are
honestly crucial as a React developer. So once again, it's completely free. And the way that
you can get it is you can join the newsletter, Import React, which is my free newsletter, you're
going to be able to click it below. As soon as you join the newsletter, you're going to receive the
design pattern document, again, completely for free in your inbox. It's honestly a no brainer.
So once again, the link is in the description,
01:00 - 01:30 I highly recommend it. Watch this video, read the
document and never look back. Alright, so let's begin. Now, unfortunately, this design pattern
that I'm going to show you doesn't really have a name, because it's actually a lot of smaller
design patterns kind of merged into one into what I like to call and really think about the correct
way to architect your application. So that means the proper way to create your components, the way
to structure and create subcomponents and combine them together, the proper way to create custom
hooks and custom functions, and also where to
01:30 - 02:00 put them in the project. And generally how to set
up and architect all of the different pieces of a React project to be as efficient as possible and
to follow all of the best practices in code and in React. So that's what you're going to learn in
this video. And the best way to learn that is to take some code, an example of code like we have
here that violates all of these design patterns that doesn't follow the best practices that is
very messy and difficult to understand. And first of all, understand why this is considered bad
code, right, that's also very important. And then
02:00 - 02:30 we factor it to see a different approach of doing
the same thing having the same functionality, just in a way that's better follows more the
best practices, and is more efficient and easier to understand as a developer, because that really
matters in a React project. So over here, we have an example of something that let me just maybe
zoom in a little bit, so you can see a little bit better. This is an example of some typical React
code that you'd probably see in a project that you work on many times, I've opened up projects that I
haven't built myself that I just joined at a later
02:30 - 03:00 point, only to see components that look like this,
right, you have your typical here wall of state, as I like to call it, right, all of these things
are different state variables, and oftentimes related to different things that don't have any
connection to one another, like we have the count, we have the name, email is visible, item selected
item, and then is dark mode, that seems like a lot of things to put in this one component, again,
all unrelated, then we have a bunch of hooks over here, we have some use effects that do some things
with the local storage, then lock some things to the local storage as well as sets the document
title selects an item, then we have a bunch
03:00 - 03:30 of functions over here that do different things
manipulating that state, right increment function, which really is not needed, because we already
have the set count here, why do we need a separate increment function, especially if we're not using
it in multiple places, right, it's a bunch of code, right, all of this code right here, and then
a bunch of JSX does doing a bunch of different things. And it's honestly confusing, if I was to
join this project as a new developer, especially as a junior developer, I would feel intimidated, I
wouldn't know where to start. And I wouldn't know
03:30 - 04:00 what to follow as the best practice, because this
doesn't follow any of them. And unfortunately, like I said before, this is the state of a lot of
these projects, these react projects out there and the projects that you're statistically going to
run into as you start working in different teams, different projects, different companies, you will
often find code like this that was written by people that didn't fundamentally understand react
how it's meant to be used, that was designed to be used. And they just wrote code that is functional,
but is in no way efficient. And in no way does it
04:00 - 04:30 follow any best practices or design patterns.
So now let's take this code, let's refactor it piece by piece, because we actually need to go
piece by piece here, that really should go as to show you exactly how messy this component is.
And I'm going to try to make this a little bit better and learn a thing or two about design
patterns and how to properly architect react applications along the way. So the first thing
that I want to do is I'm going to start breaking up this wall of state right here, right, all of
this should not belong to this one component, especially the app component, which really what is
the app component, right, this tells me that this
04:30 - 05:00 is the main entry point of the application. So it
should theoretically only do one thing, which is basically take all of the different pieces of
the application that are scattered throughout the code base and different folders, and put them
together, this component is doing none of that, it's actually holding the state being responsible
for the state and the functions that manipulate the state and all of the code required to actually
implement the functionality of account of name of all of this, right. So that's violating the
single responsibility principle, one design
05:00 - 05:30 pattern in react, which is every single component
or function should ideally only do one thing. And as soon as it needs to do something else, it
delegates it to another component or another function and then uses that function instead.
So logically, we have a count over here, which we could split up in a separate component, maybe
even a separate hook, then we have name, email, and then all of these is visible items and select
the item, they're all part of the same thing, which loosely can be transcribed to some sort of
form that is related to the user and their items. So we can also put that in a separate place. And
then we have the state here for the dark mode,
05:30 - 06:00 which again, would be its own separate thing,
dark board has nothing to do with the count, nothing to do with the user. So we can already see
a visual distinction between different sections of the state, which we can split up, put into
different places, and combine them together. So let's start with that and see where that gets us.
So first, this count over here, right, so we're going to take this put it in a separate component.
And then we're going to be able to use that count variable inside of this component and potentially
any other component that also needs account. We also have some functions over here, if I saw
them correctly, increment and decrement account,
06:00 - 06:30 these only update the count, these should also go
along with it in the separate hook. So let's do that. Let's come here to our sidebar. Let's come
here to SRC, let's make a new folder, call it hooks. And in here, I'm going to call this hook,
we're going to make a new file use count like so then we're going to open the hook. And there we
go. And actually, this should be TS not TSX. So we're just going to put it over here. Yes, there
we go. We're going to export function use count. And that is going to take for now, at least until
we need to make some changes, no arguments, then
06:30 - 07:00 we're going to come here to the app, we're going
to take this count state variable, we're going to put it in here, right, and then we're going to
import you state like this. And then we're going to take the functions over here. Aha, we also have
some use effects that set the count based on the local storage. So we'll also have to do that. So
we'll take these use effects over here, let me just see if my editor will actually let me take
them. And we're going to put them as well with the component and import use effect over here,
then we're going to come back and we're going to see we also have this increment and decrement
function, which we'll also want to take and put
07:00 - 07:30 in this hook as well, because they also belong
here. So we'll do that. And I believe with this, we have all of the functionality removed, and we
no longer have any errors inside of our component, except this JSX, which we'll also actually going
to deal with a little bit later. But in terms of our hook, this is sufficient. And I think we got
everything in this custom hook. So that's great, right. And this is also another design pattern in
React, which is custom hooks, right, as soon as you have functionality that is reused by multiple
components that could potentially be shared,
07:30 - 08:00 you put it in a custom hook, you create a custom
hook, call it use whatever the hook name is. And then you put all of the code in here that is
required to make that functionality work. And then any component or any other custom hook can
use that hook and get access to the functionality. This way, you only write it once you define
it once in one place, and you reuse it and you share it across the entire application. Now
looking at this code, there's actually a little bit of things that we can do here to even improve
this custom hook, because now all that we did is we just took the code that already existed, and
we just put it in here. But it doesn't mean that
08:00 - 08:30 the code was perfect. And that could not be
optimized, right, we can do some improvements here. And specifically, with this use effect over
here and the local storage, we can actually find a better solution for this. So essentially, this use
effect, what it does is whenever this component mounts, or whenever this custom hook actually
runs the first time, it is going to check the local storage for this actual count over here, if
it's stored in the local storage. And if it is, it is going to set it in the state over here. Now
doing it inside of a use effect is fine, because it works, it will achieve what we want our goal
to actually get the count from local storage. This
08:30 - 09:00 actually, by the nature of use effect will run
after the first render will run asynchronously, and will actually cause a rerender of the
component because it will have to set the count again, once it got it from the local storage, that
is going to be two renders to get the count from the local storage. And the first render is going
to have the count of zero, which doesn't know or doesn't include the value from local storage. So
we can improve this by killing the use effect, it's always a good idea to remove use effects
that you don't actually need. And we can just
09:00 - 09:30 default this you state over here to actually check
the local storage first without the need of a use effect. So for that, I'm going to come here at
the top, and I'm going to create a new function, call it function, initialize count like this.
And we're going to give this function over here empty for now. And then inside of the body of the
function, I'm going to take this code over here, put it inside of here. And then I'm just going
to return either the saved count, if we have it, because again, we might not have it in the local
storage. So if we have a safe count, I'm just
09:30 - 10:00 going to convert it here to a number saved count
like this. Otherwise, I'm going to return zero, right? So this is the same functionality as this
use effect over here, we're checking local storage for the count. And if we have a count, we're
returning the number version of that count, because it is going to be a string in local
storage, this function gets the count from the local storage, if we have it returns a number of
saved count, otherwise, it returns zero. So that's our initialized count function. And then we can
just give thatNow some of you might not know this,
10:00 - 10:30 and this might be a surprise to you, but maybe
you have the question, why did I use a parenthesis over here to actually call the function and give
it to useState as the initial value? The reason I
10:30 - 11:00 didn't do this, and first of all, this works, this
is function equivalent, if you do this this way, this function is actually going to get run every
single time that this component or hook renders, even if the value is only going to ever be
used initially the first time to set the count. However, if you give this here as a reference,
React is only going to run this function once when this component or custom hook mounts, get the
value, assign it here to the actual count as its initial value, and then never call that function
again. So this is a performance optimization,
11:00 - 11:30 because if you do it this way, the function gets
called every single render, but only the first time does this result actually get used, so every
other time it's unnecessary. If you do it this way, it's only going to get called once initially
on mount, put the result, and then you're good to go. So this you can do in React, and if you didn't
know about this, well, now you do. And with this, we've already improved our custom hook over here,
we've used another function over here. So this function only has one responsibility, and we're
using it efficiently inside of this state over
11:30 - 12:00 here to get the initial value of the count. That's
great. Let's move on. What else could we do? Well, this use effect over here, I mean, we just want
to log and actually set the count inside of the local storage every time that it changes.
So there's nothing really for us to do here, because we need to have a use effect that listens
to the count. And whenever the count changes, it's just going to get synced automatically with
the local storage. So we're just going to leave this as is this is perfectly fine. But then
we have the increment and decrement functions, which we actually need to return along with the
count over here of our custom hook. So let's do
12:00 - 12:30 that. Let's return. And here we're going to do
count, increment, and then decrement. And here, we're just going to make one little optimization
here, instead of just passing the functions directly, I'm going to convert these to a const.
So we're going to do const, increment equals, and this is then going to be an arrow function
that I'm going to put inside of a use callback. So we're going to do use callback like this, and
then pass it here a function. And I believe this should work, and then pass it here, the dependency
array, and then the function over here, and we
12:30 - 13:00 are good to go. And we're going to do exactly the
same thing with the decrement function. So just do this decrement. And here, set count count minus
one. And the reason we're doing this is because we're going to be using these functions inside of
our components. And we can't control where these functions are going to get used. And if they have
to be used inside of a use effect, or inside of a use memo callback, we're going to have to wrap
them in use callback to not prevent the use effect to prevent use effect actually, of running
unnecessarily, because as we know, in React,
13:00 - 13:30 functions are not stable references. So what we do
whenever we create custom hooks like this is you just wrap them in use callback, and you prevent
whoever is using these functions to have to do them to have to wrap in their own use callback,
right? That's what a lot of third party libraries do. Whenever you have a function that you're
accessing from them, you usually don't have to wrap it yourself and use callback because they do
it for you. And that's exactly what we did here. And with this, we now have our use count custom
hook, which we can directly use inside of the app component. So let's go here to the app component.
And here at the top, or even here below, we can
13:30 - 14:00 just do something like const count, increment,
decrement. And we're going to make this equal to use count like this. And now we have access to
the same values over here, count, increment and decrement that our JSX is actually using over
here, right? So this is great, we've extracted custom functionality in a custom book that we
can then reuse inside of the application. But we can do more, we can also take this piece of code
over here, this JSX, and we can actually put this in a separate component and use that component
instead. Because if you look here, what is this
14:00 - 14:30 JSX actually doing, it's just rendering the actual
count over here in a paragraph tag, and then just rendering the buttons to increment and decrement
the count. Maybe we want to show this counter on multiple pages in multiple components. So it would
make sense for us to create and put all this code inside of a custom component, and then use the use
count custom hook inside of that component. Again, make things reusable. And then if you ever need to
reuse it across the application, you can because you have it reusable in a separate component.
So we can come here, we can create a new folder,
14:30 - 15:00 we can call this one components. And we can do in
here counter dot TSX. And then over here, we can just do our JSFC, like this to create a component
called the counter component. And this is going to return exactly the same code over here, this diff,
right, we're just going to cut this over here, let me cut it correctly. There we go. Here, we're
just going to return like this. And then we're going to do here. And now obviously, we need to
have access to increment and decrement and the count as well, which we can easily get because
we have them inside of this hook. So we can also
15:00 - 15:30 take this hook over here, that we just created,
and we can combine it in its own component. And now we have all of the functionality related to
a counter, there should be counter inside of a custom component with this JSX using a custom
hook, right. And this is really efficient, we're following best practices here, because
this counter component only does one thing, it handles the functionality of what is to be a
counter, it then uses a custom hook, which again, it delegates the actual implementation of the
count of the increment function decrement function
15:30 - 16:00 to a custom hook, which is a good thing. And then
it renders its own JSX, which uses these values. So if I want this counter, I can just use the
component, if I just want to count and make my own counter in a separate component, I can also
just use the custom hook, this is extensible, this is flexible. And this is reusable. And
that's the way that most of your components in your application should look like. So now with
this, we can go back here to the app component, we no longer have a count over here. And here inside
of our JSX, we're missing the functionality. But
16:00 - 16:30 we can just add it here by saying counter like
this, what happened, we're going to say counter, and we're going to import from components slash
counter, and we have our counter application. And now this entire functionality of a counter is only
one line in this component. And we've made things better. Good, let's keep going. So we're going
to come here back to our wall of state. And we're going to continue breaking this apart and putting
things into separate components. So the next step for us to do is all of this state over here that
seems to be related to some sort of form related
16:30 - 17:00 to the user, we can first start by just putting
all of this in a separate component. And then seeing if there are other things that we can do to
improve this a little bit further. So I'm going to come here inside of components, make a new file
called this user form.tsx. And inside of here, we're just going to wait a bit, my computer's
deciding to be slow today, we're going to do our GSFC, we're going to create user form. And in
here, we're going to put all of the state and code that we had. So let's take all of this code. And
let's see what we come up with. If we put it here, we're going to have to import your state, that's
totally fine. So let's import your state from
17:00 - 17:30 react, then we're going to see what errors we
have. So we no longer have a name here. So we'll need to take this, we'll need to take selected
item as well, we'll need to take all of these functions related to name change, and then toggle
visibility and then add item and select item as well, right. So already, you can see that this
is a lot of code for something that is the user form. But really, we're not sure, right? Like
I'm saying, it's the user form, because that's what it kind of looks like. But it could actually
be something else. And that's a sign of bad code.
17:30 - 18:00 And that's a sign that something should be done
to change it to improve it. So we're going to cut all of this here. And we're going to put them
inside of here and just dump all of the code that we had inside of this and then import use effect
like this. And then there we go, we have these functions, which aren't used because we need to
actually get the JSX, we're also missing a ref over here. So let's take the ref. And let's also
take the ref as well. And then we're going to put the ref over here, I always like to make a visual
separation between my state and my functions and my ref. So always make a little gap over here, a
line break. Now we have the input ref. And there
18:00 - 18:30 we go, we're just missing everything in the return
function. So let's come here to our JSX. And I believe it's all of this over here. Yeah, all of
this has errors until the last paragraph, which is related to dark mode, we can just take all of
this and put it here inside of the form component like this. And then let's just fix the formatting
and save and we have an error over here. Yes, we need to put all of this in a form, because this
is a form and this wasn't done actually. So again,
18:30 - 19:00 another sign of something that we can improve.
And now we have everything in a form, we have the same code, the same functionality, just in
a separate form. That's good. Even though we didn't really improve anything, we did put this in
a separate component. So now it follows the single responsibility principle, there is a separation of
concerns, and this already is better. So then in the app component, we can just come here. And here
we can just use the user form. So we can do user form, import this from component slash user form.
And already look at our app component, look at how
19:00 - 19:30 much smaller it is. If I also just clean up here,
these imports, these unused imports over here, this use effect and this use ref, look at how
small this component is, right? This is now 22 lines of code, including the actual imports, we
have three lines of imports over here. That's what you want to do. Whenever you see a big
component in react, you want to ask yourself, what is this component doing? And what should it
be doing? Is it doing too many things? Can I break things up into multiple things and put them right,
that is the design pattern that I'm trying to teach in this video. Because you take a component
that's really big, really intimidating, you split
19:30 - 20:00 it into multiple parts, and then you turn it
into something like this, this is super easy to understand, super easy to work on. And if you want
to access the counter, you go to this component. If you want to access the form, you go to this
component, and everything is in its proper place. And it's very efficient. So then going back to our
user form, let's look here and see what else we can improve. Well, the first thing that I'm seeing
here is that this use effect essentially changes the document title to hello name as this form is
being changed.I understand why this is being done,
20:00 - 20:30 but I generally don't think that we need this.
And if we did want to implement this, I will not put this as part of the user form, because
now the user form is starting to change things that are outside of its scope. And generally,
you don't want to do that in your application. So because this is such a feature that really
isn't necessary, like why would you want to update the document title to the user's name as they
type? What if they type some random gibberish, right? We're just going to remove it. And this is
perfectly fine. And in your projects, if you're working in code that somebody else wrote, you
have to look at that code. And you have to ask
20:30 - 21:00 yourself, is this code pertinent? Is it needed? Or
can it be removed? Because if we remove it, again, we're removing an extra use effect, we're removing
the chance for something to go wrong and an extra render cycle in the component. And that's always a
good thing. And then here as well, we have another use effect over here, which simply if there's
a selected item, just logs it to the console, right, we don't need to do this, we don't need
to log this. And this was probably here at an earlier stage of development, when they wanted
to log that this was working correctly. And then maybe this just got forgotten and found its way
to production, right. So it's our job as good
21:00 - 21:30 developers to spot these things and say, hey,
this isn't needed, we should actually remove it and make this component a little bit simpler.
And now as you can see, we no longer even have use effect in this component, which means that we
can remove it directly from the imports over here. And we're that much better for it. And then let's
see what else we can do. Well, we have these two functions here handle name change handle email
change, which is essentially just set the name and set the email to eat our target that value.
This I generally don't like to do this because
21:30 - 22:00 this is creating a function for nothing, I would
rather just inline these functions themselves directly inside of the JSX and be done with it.
Another advantage of doing that is you don't have to retype this event over here, because the type
can actually be inferred from the component are using it. And so I'm going to come here and just
remove both of these functions handle email change handle name change. And I'm going to come here in
the JSX. And instead, I'm just going to do here, access the event, which is again, the type
inferred. And here we're going to do set name. And we're going to pass your what happened
set name. And we're going to pass your
22:00 - 22:30 E dot target dot value. Again, same functionality
as we had before, we just inline it and it's a little bit simpler because we don't have to define
a function over here. I generally like to do this. This is also a smaller design pattern that you
can apply in your rec projects. And then we can do the same for the email, I can access the E over
here. And then here, we're going to do set email, E dot target dot value like this. Now, ideally,
you wouldn't even do these as proper states, you would use something like React hook form to have
a proper form management solution. In this case,
22:30 - 23:00 we're not going to bother, I'm going to try to
keep this video a little bit shorter. But yeah, ideally, you would use something like React hook
form, because it makes all of this a lot simpler. And then we have all of this functionality related
to the items. So here we have items, which is a state of an array, right of strings, then we
have is visible, which essentially toggles the items. As you can see over here, if is visible,
we're rendering all of this diff over here. So that's all of the items where we're looping all
of the items and also the button to add item. I'm not saying this is good code, this is just
the code that we have and that we have to work
23:00 - 23:30 with. And oftentimes, you don't get to choose
the code that you're working with. But you have to choose the way the only thing you get to
choose actually, is the way they approach solving it and making it better. So that's what we're
doing. So what I would do at the very least, because I don't want to take too many risks,
and also maybe introduce some bugs, I just want to put everything that is related to items
in a separate component, even in the same file, just again, to have a separation of concerns to
put things that are different in different places, and see if there's anything else that we can do
later on to actually improve it. First, I'm going
23:30 - 24:00 to come here at the bottom of this component. And
I'm going to create a new component over here, call it function, user form items. And here, we're
just going to put nothing for now, I'm defining it inside of this file, because this component is not
going to be exported. And it's only going to be used inside of this file. So instead of creating a
separate file for it and having to import it, and then always navigate between two different files,
I'm just going to put it here. And this is fine, you can have multiple components in the same file.
And this is also a smaller design pattern that is
24:00 - 24:30 perfectly valid to use in React applications. And
here, we're just going to do a return. And we're going to pass all of this state over here. Right.
So let's see what how did I do it over here. So we have the button as well, right. So we're
going to take all of this code over here, right, just everything that is related to items, cut it,
and then just return it over here. And then we also have to return it, I believe in a div, what
happened, did we miss something, let's just first return it as a fragment just to make sure that we
get it right. So we're just going to do here. And
24:30 - 25:00 then this should be fine, I believe I missed a div
somewhere, because there is a div. And this is a div. And this should be let's just put a div here
for good measure, div, div like this, and then we should be fine. And then we just need to get
toggle visibility is visible over here and just get the ref. So first, let's start with the ref,
because I feel that's more important. So again, we're going to take this ref, we're going to put
it inside of this component over here. So now we have access to the ref. So that's good. Then we
need the toggle visibility function. And then we need a state for is visible. Now because this
state is being updated inside of this component,
25:00 - 25:30 we have the button here to actually, where is it
to show the Yeah, there we go, the button to show the on click to toggle the visibility on click,
that stage should belong to the user form items component. So let's take the state over here. And
let's take is visible and put it here inside of the user form items component, then this toggle
visibility function. Again, we can just inline this because all that this really does is it just
sets is visible to the opposite of is visible. So first of all, we don't need to do this anymore,
we can just remove it. And here we can just inline
25:30 - 26:00 it like this. And we can just do set is visible,
and then pass it the opposite of is visible. And again, we don't have to create another function.
And this is a small step that we can do to improve this, then we also need the function to add
an item. So I feel that this also belongs here because we have the items over here. So let's
also take the function to add an item. And let's put it over here inside of this component. And
again, I'm not improving anything specifically, I am just putting things in separate places just
to make it a little bit more clear to understand
26:00 - 26:30 what's going on. And then naturally, things are
going to come up that we can use to actually improve this. And then what we need is we actually
need the items and then the set items function, which again, all seem to belong to this component,
as well as the selected item component all seem to belong to this component. So we should also put
all of these things there. So let's just take these because these are no longer used. And let's
put them and again, make some space in here to not make this more complicated on ourselves. And here
we can just put our state, let me just organize it
26:30 - 27:00 properly to put state with state because that's
just a little bit better. And then we have our three state variables over here is visible items
and selected items. This is more plausible that this relates to the same thing, right? This
is all related to the items on the user form, right? So that's a good thing. Then we have
the ref, which is only used in this component, then the function to add the item. And then the
select item function, which honestly, again, we can just inline this because instead of select
item, we can just use set selected item. And this
27:00 - 27:30 should work, set selected item. And again, we
have no type errors, this is perfectly fine. And we can just remove this function. And now this is
our component user form items. It's super small, concise, and again, only relates to the items on
the user form, which means that we can come here and we can just do user items form user form items
rather, and just use the component instead. Again, this made this user form component smaller,
it now only has two pieces of state we want to from how many we want to five from two, which is
good. And we have all of this stuff related to a
27:30 - 28:00 form over here. And then everything else related
to the items is in a separate component defined in the same file because it doesn't need to be
exported. It's only used in this file. And again, this one's also manageable three pieces of state,
one ref over here, one function, and the JSX to actually make this work. Now, obviously, we can
improve this a lot further, we can create custom components for like all of the items over here,
and then reuse them across the application, we're not going to do it because I feel that you've
understood by now, the actual point of this video,
28:00 - 28:30 the actual point of this most important design
pattern, which is that you take things, you split them up, you break them apart, and then you
reuse them across the application, because that is efficient, and that is scalable. And actually,
I just realized over here that we have something missing, we have a form, but we have actually no
function to submit the form. So we probably want that. So we can do something like async function,
handle, submit. And then this would take maybe some data, this would take the E here. And that's
going to be I believe, form event like this,
28:30 - 29:00 there we go, import this from react. And here
we can just do something with the data. So do something with data, right, send it to a back end
or something. And then here we can do on submit, and then we can do handle, submit. And there we
go. Now we have a function to actually submit our form, which this component didn't have before,
right. So there we go. Now we have the user form component, it's super small, it is being used here
inside of the app component. And everything is starting to look a little bit more clear, a little
bit more easier to understand, and definitely less intimidating, which is good, we're almost done.
And finally, the last thing that I want to do
29:00 - 29:30 is all that we have left is this is dark mode
property over here. And this function to toggle it, which again, is just used here. So what we can
do is essentially create a custom component, put all of this functionality inside and be done with
it, just use that component in here. So let's come here inside of components, we're going to create
a new component, we're going to call this one dark mode toggle dot TSX, this is going to create a
new component, we're going to do our JSFC, that is going to be dark mode toggle like this, we're
going to take the same code that we have here,
29:30 - 30:00 we're going to put this here inside of dark mode
toggle, we're going to import our use state over here, then we have our function, then we're going
to take this div over here, we're going to cut it, and we're going to return it over here as
what this component returns. And now again, we don't need to toggle dark mode, we don't
need this extra function, we can just kill it, we can just do let's kill it first, we can just
do set dark mode set, call this as a function, actually.And now we have the same functionality
in a custom hook, no redundant function. And we
30:00 - 30:30 can just come here to our app component and we can
do over here, we can just use dark mode toggle. And now we have almost the same functionality, we
still have an error here, but our component now is 15 lines of code imports included, and actually 14
lines of code imports included. And it's so small. And that's how most of your components should be.
I know I'm saying this a lot, because I really
30:30 - 31:00 want to drill this into you. This is how most
of your React components should be. If you see a component that's much larger, that's a code smell.
And that's a sign that something has to be changed and improved to make this better. Now back to this
area here. Yes, we're no longer having access to is dark mode, because now it's only inside of this
component. And the thing is, this is actually bad code, because this is dark mode property is only
local to this component here, it's not being shared across the application, you wouldn't want
to do this. Ideally, you would convert this into a
31:00 - 31:30 context that holds the application appearance,
the state of the theme, if you will, if it's dark mode or not. And then you would access that
property over here in the app component or any other component using a custom hook that accesses
the context, I'm not going to do it in this video, because if I did, it would just make this
video too long. But I have a bunch of videos, I even have a tutorial video on use context that
shows you exactly how to do this. But again, I wouldn't do it exactly like this, I would create
a context share this value, because it just makes more sense for something like dark mode. But yeah,
I mean, look, we've done a lot of great things in
31:30 - 32:00 here, right? So actually, let's just fix this one.
Because again, we're not going to use it, let's just pretend that it's not actually useful in our
actual project. So we can just remove it. And this is the final state of our app component, three
imports over here, three different components, the app component, and then it just renders
everything else, right? This goes back to what I said in the beginning of this video, you take a
look at this app component. And you're thinking, what should this app component actually do? It
shouldn't implement every single feature of the
32:00 - 32:30 entire app, your entire react application
should not be one main component. Instead, it should take all of the different pieces of
code. That means components hooks functions from across the application across different folders,
and put them all together and just render them, it shouldn't implement any of them, right. And
that's exactly what we've done here, the app component is super small, it uses everything
that it needs. And the actual implementation is delegated to each of these components. And
then each of these components are super small, super simple, super reusable, they all only do
one thing, they follow the single responsibility
32:30 - 33:00 principle. And we have the same here for the
document toggle, we have the same thing here for the user form, we've refactored this, we've
made things a little bit better. Obviously, there's more things we could do, we will probably
want to create a custom component for the input over here. Maybe we also want to create a custom
component for the button, right, I'll leave that for you to do, you can actually get access to this
repository in the description, I'm not going to do it. But the concept remains the same, everything
that can be shared, everything that is reusable, put it in a separate function component, and just
use it across the application. And that's exactly
33:00 - 33:30 what we've done here. And I think honestly,
the counterexample is the best example of this, because we have a custom hook that we created,
and we're using it inside of a custom component that we created. And this is super flexible,
super reusable. And it's just beautiful. It's art at this point. So really, again, going back
to what I said in the beginning of this video, if there's one thing that you get from my videos
of all the videos that you watch, it's this it's this design pattern, how to properly structure
and architect your react projects, your code,
33:30 - 34:00 your components, your functions, your custom
hooks. Because if you do this, and if you understand this, and you really get this, I will
be very surprised if you actually write bad code in your applications, because this makes it very
hard. If you split everything up, it's very hard to make messy code. And you're just going to
end up with beautiful code that is easy to read and understand. And that's what you want. That's
what this whole concept of design patterns is. And that's what the whole concept of this video is.
And hopefully by now you got that right. So again, you're going to have access to the code for this,
the actual repository is going to be linked in
34:00 - 34:30 description. And remember, you also have access
to 10 other design patterns that are equally as important as this one, just in an actual document,
because if I made a video with all of these, it would have been like a five hour long video
in a document that is completely for free, I went through the painstaking effort and time to
actually make this for you. And I give it to you completely for free. The only thing that you have
to do to get it is just sign up to the newsletter, which is completely free. As soon as you sign up,
it's linked in the description, you're going to
34:30 - 35:00 get the document in your inbox. And you can
continue with this video and actually apply those to your react projects. And like I said, in
the beginning of this video, for the last time, never look back and never write bad react code.
Again, if you enjoyed this video, and you want to see more videos just like this one, make sure
to leave this video a big thumbs up. You can also click here to subscribe. Or you can click
here to watch a different video of mine that YouTube seems to think that you're really going
to enjoy. And with that being said, my name has been Darius Cosden. Thank you so much for watching
and I will see you in the next video. Ciao ciao.