Top 5 Lessons Learned Building React Applications
I recently gave a talk on “Lessons I Learned building React Applications”, at a conference. I thought this is a good talk that needs to be documented as a blog post. So here we are.
In this blog post, I am going to go over my top 5 lessons on building React applications over the years. Let’s jump right in.
Lesson 1: Use Functional Components
Class components in React, are a story of the past. Class components are confusing to people and machines. Here are my top reasons on why you should start using functional components for your React applications.
Why Functional Components?
- Simpler to learn and write.
- Less code.
- Easier to maintain and test.
- Availability of hooks within functional components.
Hook is a special function that let’s you hook into React features, within functional components.
So if you are starting out and learning React, you don’t have to worry about class components. You can directly learn functional components. If you already have a React app, just ensure going forward you write your new components as functional components.
Note: Keep in mind that React still supports class components, so you don’t have to rewrite your class components into functional components.
import React, { useState } from "react";const YesNoButtonComponent = () => {
const [button, setButton] = useState(""); const onButtonPress = (buttonName) => {
setButton(buttonName);
console.log(buttonName);
}; return (
<div>
<button onClick={() => onButtonPress("Yes")}>Yes</button>
<button onClick={() => onButtonPress("No")}>No</button>
</div>
);
};
In the example above you can see a React functional component in action, utilizing the useState hook!
Functional components are the future of React!
Lesson 2: Break down components — when needed!
Each component is a building block that is a reusable piece of UI. Putting them all together results in a complete application.
Here is a simple strategy I follow, when I need to break down components within an application.
When do I break down components?
- Managing state is becoming a nightmare!
- Performance concerns with re-rendering of the component or application.
- Code readability takes a hit.
- Working with multiple developers on the codebase becomes challenging.
- Testing the component is harder.
If you encounter any of these problems listed above, it is a good idea to start breaking down the component into smaller components. There is no hard and fast rule on how large or small your React component needs to be. If you notice any of the problems above, it is a warning sign that the component needs to be smaller.
Lesson 3: TypeScript is a life saver!
In the last year or so I have switched my projects to TypeScript. I didn’t realize then, on how much better my developer experience was going to be with this switch.
Here are some top reasons why I think TypeScript is a life saver:
- Catch problems early on at compile time.
- Intellisense is accurate.
- Easier to refactor code.
- Readable code.
- Easier to maintain and test.
- High quality documentation with TSDoc.
type HeadingProps = {
title: string;
bold: boolean;
}export const Heading = ({ title, bold }: HeadingProps) => {
return (
<div>
{bold ? "Bold Title: " : "Regular Title: "}
{title}
</div>
);
};
In the example above, you can see TypeScript in action. The component Heading accept the props title and bold of type HeadingProps. Anytime we invoke the Heading component we will have to pass to it, all the props with the appropriate types. Your IDE will throw an error, if you either miss a prop or pass a prop of incorrect type as shown below.
This is quite awesome while developing React components, to get instant feedback while coding.
Lesson 4: Start with local state!
A lot of the times, when React projects are started, developers immediately think that they somehow need an external state management library. It is not uncommon to see teams setup Redux/MobX/XState or similar libraries when they get started with building a React application.
I would recommend to start with local state for your React application, and make state management decisions as your application grows. Often times, your application may really not need complex solutions for state management. So why bring all the added bulk of libraries, if you can do away with them?
Here is a workflow you can follow while your application grows:
1. Start with local state first: When you start building your application, keep state local to each component. And this may suffice most of the times, and you can use the useState hook to manage the state.
2. Pass down state via props: If a child component needs access to the state from a parent, it can then be passed via props from the parent to child component.
3. Lift state up: There can be situations where a non-child component needs access to data from another component. In this scenario, you can use the concept of lifting state up to the common parent component.
4. Use context: Context is designed to share data that is global for a tree of React components. If you want to avoid passing certain props through multiple layers of components, then use context. Context is usually used for data such as demographic information, theme, etc.. that are needed by most of the components.
5. If all of the above is not enough, then go for external state management: If you have tried all of the above methods, and your application’s state is still growing, and you think it could benefit from using an external state management solution; then go for it. There are plenty of options such as Redux, MobX, XState and so on, that you can bring into your application
Lesson 5: Test, Test and Test!
Last but not the least — Test your code! Once you follow all the other best practices in React, your code should be easy to test. There are different types of testing that you can do with your React application, and I recommend all of them.
Unit Tests
Jest is the most popular testing framework for unit tests. There are other frameworks as well like Mocha that you can use. Unit testing is the most basic form of testing, that lets you test the smallest units in your code.
Component Tests
Everything in React is a component and it follows the component based approach. Your components are individual reusable units that can be tested efficiently. This form of testing is very crucial in React.
Kent C.Dodd’s React Testing Library is a lightweight solution to testing React components. It provides simple React DOM testing utilities that encourage best practices with testing. Many teams have had good success in testing their components with this library. Do check it out, if you haven’t.
Automated End to End Tests
This type of testing is basically testing the application as a whole. It simulates how a user will click through the application and test it in a browser. The most popular and easy to use framework for end to end testing JavaScript (or anything that runs on a browser) is Cypress. I have used Cypress to test front end applications, and it is a total breeze to setup and get running. This will entail testing in a realistic browser environment and I highly recommend including these tests to your React app.
Conclusion
Well that’s a wrap! I hope you enjoyed reading this article on lessons I have learned working with React over the years. There is no set rule while developing React applications. React itself is a flexible library, giving developers the freedom to make decisions. With freedom comes responsibility, which is what makes React interesting to me.
If you liked this post, don’t forget to share it with your network. You can follow me on twitter @AdhithiRavi for more updates.
This article was originally published in https://programmingwithmosh.com/
I am an Author, Speaker, and founder of Surya Consulting, Inc.
Through my Pluralsight courses, I have taught over 75,000 students topics such as React Native, GraphQL, and Cypress.
Link to my courses:
https://app.pluralsight.com/profile/author/adhithi-ravichandran