Are your react components really reusable?
Oct 30, 2024 at 11:00 am
When you build a user interface with React, you will first break it apart into pieces called components. Then, you will describe the different visual states for each of your components. Finally, you will connect your components together so that the data flows through them.
We have all been following the thinking in React model in our mind while developing web apps and yet we end up re-writing the same code multiple times instead of using reusable components. Why?
I insist you to stop for a moment and try to find the differences in the components you created in some past projects and some recent ones! Did you find anything strange?
Overtime the complexities of projects increases, more and more components are created but how many of them are being re-used? Can you find the spots where you created a new component which was never needed? Or you could create a new component that can be used in both situations?
Let's start at the basics and work our way ground up to understand how complex designs systems like Giest (Vercel) and Blade (Razorpay) are implemented in React.
Reusable Components
In React, reusable components are self-contained, modular pieces of UI that can be used multiple times within an application or across different projects, which promotes code reusability, maintainability, and efficiency.
Too complicated, right? I know.
Lets understand with an example of a simple Button component.
Requirements:
- Colors : Green, Yellow, Cyan, Red and Purple
- Size : sm, md and lg
- Radius : sm, md and lg
Let's get it out of the way that we don't need to create separate components as GreenButton, RedButton, etc as shown below.
We can observe that with the help of props we can combine both the components into a single component. We will use clsx with tailwind css to conditionally assign background colors and other css classes to the Button components.
By mapping css classes for each variant with props, we constraint the use the component and full-fill our requirement.
There are a few problems with this approach:
- No accessibility.
- Native HTML props of
buttontag can't be used. - States of the button can't be controlled.
- The
refproperty can't be utilised.
Better Approach
Let's break down our requirements into unit properties that map to some css classes. Consider these classes as presets of the component, then the combination of properties make a set of components from the design system. Aditionally theses presets can be overriden at the time of use-cases as well. This process can be broken down into three steps :
- Write preset css classes (variants)
- Break component in smaller components.
For example,
Cardcomponent can be broken down into,Card,CardHeading,CardDescription,,CardContent,CardActioncomponents. - Use multiple variants using props as defined in step
Now, we can use a single Button component to create all kinds of button varying in color, size and radius. Adding new props is simple and for modifying current styles just add the css classes you require in the ButtonVariants. Is the component typesafe? You bet it is! Can I use ref of the button? Yes! How? (Hint : button.tsx)
Can you customize this component any further?
Yes! Let's re-create the Get Started and Learn Next.js buttons from Next.js website's landing page.
We created a component that follows our design system and can be customized in any way you wish!
Can you extend this principle of creating reusable components to create a List, which also has state and data and action upon interaction with user?
References
- Lessons learned from building reusable UI components
- Part 3: Component Structure - Building Reusable and Maintainable Components in React!
- Modularizing React Applications with Established UI Patterns
- Scaling React Apps with Reusable List Components
- The cost of convenience
- 8 Tips for Building Awesome Reusable React Components
- How to Build Reusable Components Using React
- Thinking in React
- Blade (Razorpay)
- Giest (Vercel)