5 Best Practices for Refactoring React Components
Learn how to refactor React components with these 5 best practices that focus on code readability, maintainability, and performance.
The question
React.js has become the most popular view library for web components, evolving across multiple features that today make it a complete tool to create amazing web applications.
The community has grown exponentially, especially in the past 2–3 years, populating the web with thousands of tutorials regarding this technology.
So, what every beginner should do when starting to learn React, as I did when I began my path at Codeworks, is reading the documentation or tutorials to create their first component.
But here my question: are you sure is your React components are following best practices? Or simply, do they just work?
What a dirty component looks like
To better explain my point, let’s take a look at the following React component:
This is a fully working React component ready to be used multiple times throughout the application, rendering a list of buttons which serve a purpose and show what is the last clicked button. Simple enough.
You might think “Well… if it works it’s fine!”
But what if you knew how to write the same component in a few lines, compared to the 62 you have right now? Let’s start with the cleanup! 💎
Prefer functional components with React Hooks
With the introduction of Hooks in React 16.8, we enable the power of having a stateful component (if we need to handle any logic) using a functional component over a class declaration.
We won’t talk about Class vs Functional components or React Hooks in-depth in this article. However, it is known in the React community that it is preferable to create Functional components, especially now that we can use the power of Hooks.
So let’s see what the component looks like after the first refactoring:
All right, our component is already shorter and we dropped the class syntax, but still have to do many optimizations.
DRY the wet!
Can we recognize any pattern in this component? Looking at the code, it seems like we render a similar button element every time which accepts some props similar for each one, a perfect case to cut in small parts this long component.
So we can refactor it creating another small functional component to render the button, passing some properties like action
, setClicked
, and title
:
Ok, our component starts to have a better shape, but there is still margin for improvements, let’s go on!
Proper naming & props destructuring
setLastClickedButton
is a descriptive name for our setter function, but we need to keep our code readable and short, so it’s important to keep the names we use minimalist and essential. We will rename it setClicked
.
Also, whenever is possible, destructuring from the props object what you need can avoid continuously repeating the props
word. In our ListItem
component, we now access the props by name in the destructured function argument — { action, title, setClicked }
.
Let’s see both changes:
Great, we drastically reduced the length of our component declaration, but we can still do it better! 🚀
May the PropTypes be with you!
After this cleanup, it is time to apply the absolute best practice when writing a component! With PropTypes, we can validate the received props to avoid errors due to different data types, for example, receiving the string “0” and trying to strictly compare it with the number 0 “0” === 0 -> FALSE!!!
:
Split into small pieces
Guess what — our component is more or less as long as the initial version, but look closer at the code we have now.
We see two different components that we can divide into two modules, making them reusable across the whole app.
Conclusion
This cleanup applied to our initial component shows some good practices to follow when you start digging into React components.
Of course, there are tons of other optimizations we could perform on this final result, but one step at a time. Five good practices to follow are a good starting point 😉
Last updated: