Writing a cleaner Code in React by following SOLID Principles
SOLIDify Your React Code
AI Generated Video Summary
Clean code is easily understood, readable, changeable, extensible, and maintainable. SOLID principles enforce good practices for scalable and maintainable software. The Single Responsibility Principle (SRP) ensures that components have a single reason to change. The Open-Close Principle (OCP) allows components to be easily extended without modifying the underlying source code. The Liskov Substitution Principle (LSP) enables swapping child elements within a subtype component. The Interface Segregation Principle (ISP) states that components should only depend on the props they actually use.
1. Introduction to Clean Code and SOLID Principles
Hi everyone. I'm Islam Aboud, a full stack software engineer working with TopTel. Today, we'll cover Intro to Clean Code and the five SOLID principles. Clean code is easily understood, readable, changeable, extensible, and maintainable. SOLID principles, introduced by Robert C. Martin, enforce good practices for scalable and maintainable software. They are Single Responsibility, Open Close, LispConv Substitution, Interface Segregation, and Dependency Inversion. SOLID works well in team environments, and using TypeScript with React allows for cleaner code following these principles.
Hi everyone. I'm Islam Aboud and welcome to today's talk about solidifying your React code. So a little more about me. I'm Islam Aboud, a full stack software engineer working with TopTel. I'm the founder of the Code One YouTube channel at youtube.com codeone. Also, I'm a big fan of helping developers build better web applications with like educational tutorials and video tutorials on YouTube and blog posts and stuff. And you can find my portfolio at islamaboud.com.
So this is what we are going to cover today from Intro to Clean Code to actually going through the different solid principles and exactly how you can apply them inside of React. So first, let's go ahead and see a quick introduction into Clean Code. So code, we tell or we say code is an actual clean code if it can be understood easily by everyone on the team. So clean code can be read and enhanced by the developer other than its original author. So anybody on the team, even though he's not like the right person or the original person who wrote that piece of code, he can easily understand exactly what's happening. So with understandability comes readability, changeability, extensibility, and most importantly, maintainability. So here it can actually read about, you know, clean code, best practices, and how to write clean code. What is the best practices to make your code cleaner, easier to read by everyone, and of course, eventually, you would actually be able to write better code.
2. Single Responsibility Principle (SRP)
The single responsibility principle (SRP) states that every component should do exactly one thing. It ensures that components and functions have a single reason to change. For example, a bad component may have multiple responsibilities, making it hard to read and understand. In contrast, a good component follows SRP by encapsulating logic in hooks and rendering encapsulated components.
So starting with the single responsibility principle or the SRP. So for the original definition, every class should have only one responsibility for the extrapolated definition to make it work with React. So every component should do exactly one thing. So SRP is the role to making sure our component and functions or modules are responsible for doing one thing only and thus have only a single reason to change.
So to better understand SRP, for example we can take this simple React component here which is like the bad component here. So it's a normal component. It uses the useState in here. It has a function to fetch the product, has a useFx in here to call the fetching of the product and here's some function to handle the rating and the button click and everything another one using usingMemo to filter the products depending on the rating. And of course it renders a bunch and I mean a bunch like a lot of GSX in here. All of it is actually really complicated and it's really hard to read. You don't know exactly what's happening. So all the filtering stuff are happening. The rating component is being rendered. I'm like mapping through the SVG here to render the stars or the rating stars and a bunch of stuff and literally very hard to read. Now if we go into a better implementation like the good component here, it's a lot better and now it uses actually a hook which is used products to do the fetching. That actually has encapsulated all the fetching. Use another one. Use rate filtering here to do the filtering stuff. So everything is encapsulated inside of that hook and we just render these two components. So everything, all the logic in the GSX has been encapsulated into like the filtering component and here we're just mapping it and we're rendering this encapsulated product component.
3. Open-Close Principle (OCP)
The open-close principle (OCP) states that software entities should be open for extension but closed for modification. In the context of React, this means that a component should be easily extended without modifying the underlying source code. By using icons instead of roles, we can make the button component more flexible and avoid the need to change the source code for every new feature.
Now, the second principle, open-close principle or OCP, original definition is software entities should be open for extension, close for modification. And now explorative definition for React is a component should be easily extended without modifying the underlying source code. So OCP is just for making extendable components that are future proof without actually going inside the components and changing the source code for every new feature you're trying to add.
So if you look at this button component here, it's pretty simple component. It's easily, it takes like a text in here to render inside of the button. It takes a role. And a role in here in TypeScript, like it can be either back forward, main or not found. And it simply renders a button and of course, depending on the role, whether it's forward, it renders a particular icon, whether right or left. Now this is actually really bad because everything is encapsulated. So every single time you want to add a new icon, you got to go ahead and add a new role. And if you add a new role, you go ahead and actually change the actual source code of the button. But instead what you should do if you go to the good implementation in here, so instead of passing a role into that one, we can simply pass like an icon. And of course, we can just like specifically tell it like outside when we try to render stuff. So instead of using a role forward and back and whatever, so we can let the icon in here, we can render a React node immediately. You can just pass it to the button and it can render without even needing to change the source code.
4. Liskov Substitution Principle (LSP)
The Liskov substitution principle (LSP) ensures that a child element or component can be easily swapped for the same element type within a subtype component. For example, by extending input HTML attributes from the HTML input elements, we can pass any props the input takes through the search input component.
The third one is Liskov substitution principle or LSP. Now the original definition is subtype objects should be substitutable supertime objects. Now for a more clear definition, a child element or a component should be easily swappable for the same element type. So LSP is just like for making sure that we can easily swap some elements with other elements of the actual same type within a subtype component. It might seem a little weird. You will better understand within a simple example.
So let's say we have this simple example in here where we have this interface where it actually tells you the search path. Now for example, let's say we've got this search input component in here that actually underlining and he uses an input component. So this input component here is our original component that actually takes a lot of props so we can take a class name, ID, type, value, on change and so on and so forth. Now because this search input component is actually encapsulating the input elements in here, so it has to actually provide all the prompts that the input needs through the props actually uses. So for example, when you say I search props is actually the props of the search input and here we're only providing on change and value, but the input in here of course it takes a lot more stuff. So a lot more props are actually needed. So instead of just doing it this way, you can actually go ahead and actually extend. So you do extend input HTML attributes from the HTML input elements, so instead of doing that you can comment the code and now you can actually pass whatever you want from like the placeholder to any prop the input takes through the search input component.
5. Interface Segregation Principle (ISP)
The interface segregation principle (ISP) states that client classes or objects should not depend on methods or properties they don't need. In the context of React components, this means that components should not depend on props they don't actually use. For example, a bad component may pass unnecessary props to another component, breaking the ISP. Instead, components should only pass the specific props they require.
For the fourth one is interface segregation principle, or ISP. So for your definition is client classes or objects that use an interface should not be required to depend on methods or properties they don't know. And here for a simpler explanation is components should not depend on props they do not need. So ISP is simply for preventing the creation of overly large monolithic interfaces that are forced depending components on props they don't actually use. So example, we've got this bad component in here that actually breaks the ISP law in here and it uses it has another component side of it as the thumbnail.
Now the thumbnail here to render it doesn't need the whole products, but even though they If you look at it, it actually passes it through a whole product. So we go inside that thumbnail components. It only uses the products image. All it needs is the image URL or the image property from the products. So there is no need to passing the whole objects for all the facts, or you simply going to do is actually go to a good component here. So if you look into the only passing the image URL, so you only takes the image URL instead of the whole products. There's literally no need to pass in all of that props, if the component or the thumbnail components is not going to need that or even is not going to use that at all.