0% completed
When learning React, it’s easy to focus on just making things “work”. However, understanding and applying best practices will help you write cleaner, more maintainable, and scalable code from the start.
In this section, we’ll explore best practices you can employ to help you build better React applications.
1. Use Functional Components Over Class Components
React initially relied on class components, but with the introduction of hooks, functional components are now the preferred way to write React applications. Functional components were used throughout this course because they are simpler, easier to understand, and more concise.
Why use Functional Components?
this
or lifecycle methods explicitly.useState
and useEffect
, which make handling state and side effects easier.Let's look at a counter application in a class component and how it is represented in a functional component.
class Counter extends React.Component { constructor(props) { super(props); this.state = { count: 0 }; } increment = () => { this.setState({ count: this.state.count + 1 }); }; render() { return ( <div> <p>Count: {this.state.count}</p> <button onClick={this.increment}>Increment</button> </div> ); } }
Here’s the same counter as a functional component:
import React, { useState } from "react"; function Counter() { const [count, setCount] = useState(0); return ( <div> <p>Count: {count}</p> <button onClick={() => setCount(count + 1)}>Increment</button> </div> ); }
Looking at the functional representation of the counter component, you can see it is more cleaner, concise and involves less code.
2. Keep Components Small and Focused
In React, components should do one thing and do it well. Breaking your application into small, focused components makes the code easier to read, debug, and maintain.
Why use Small Components?
Example
Let's look at a poorly structured component and how it can be split efficiently for easier management.
function App() { const [tasks, setTasks] = useState([]); const addTask = (task) => { setTasks([...tasks, task]); }; return ( <div> <h1>Task Manager</h1> <input type="text" placeholder="New Task" /> <button onClick={() => addTask("New Task")}>Add Task</button> <ul> {tasks.map((task, index) => ( <li key={index}>{task}</li> ))} </ul> </div> ); }
This component handles too many responsibilities. The best approach is to split it into smaller components:
function App() { const [tasks, setTasks] = useState([]); const addTask = (task) => { setTasks([...tasks, task]); }; return ( <div> <h1>Task Manager</h1> <TaskInput addTask={addTask} /> <TaskList tasks={tasks} /> </div> ); } function TaskInput({ addTask }) { return ( <div> <input type="text" placeholder="New Task" /> <button onClick={() => addTask("New Task")}>Add Task</button> </div> ); } function TaskList({ tasks }) { return ( <ul> {tasks.map((task, index) => ( <li key={index}>{task}</li> ))} </ul> ); }
In this example:
Think of your React components as a team. Instead of assigning all the work to one person (a giant component), delegate tasks to specialized team members (small components).
3. Leverage Reusable Components
Reusable components save time and effort by reducing duplication and making your app more consistent.
How to Create Reusable Components
Example
Let's look at a scenario whereby we need buttons in different places in our application. Instead of writing separate buttons, we can create one reusable button component and use wherever we want:
function Button({ onClick, label, color = "blue" }) { return ( <button style={{ backgroundColor: color }} onClick={onClick}> {label} </button> ); } // Usage function App() { return ( <div> <Button label="Save" onClick={() => alert("Saved!")} color="green" /> <Button label="Delete" onClick={() => alert("Deleted!")} color="red" /> </div> ); }
In this example:
onClick
, label
and color
set to a default of blue).style
: Sets the button's background color using the color prop.onClick
: Executes the function passed through the onClick prop when clicked.label
: Displays the text passed through the label prop.4. Comment on Code for Better Readability
As your application grows, your future self (and your teammates) will thank you for leaving helpful comments. Comments explain the "why" behind the code, especially when the logic is complex or not immediately clear.
Best Practices for Comments
Here, is an example of a good commenting style:
function fetchData() { // Fetching data from an external API fetch("https://api.example.com/data") .then((response) => response.json()) .then((data) => { // Process and set the fetched data setData(data); }) .catch((error) => { // Handle any errors during the fetch console.error("Error fetching data:", error); }); }
And this is a bad comment:
// Set the data setData(data); // This is obvious from the code itself!
5. Use React DevTools for Debugging and Performance
As web developers, we 'live' in the browser; you could say it's our playground. And as your React application expands, debugging and ensuring optimal performance can become challenging. This is where React Developer Tools (React DevTools) comes to the rescue. It is a browser extension that provides powerful tools for inspecting, debugging, and optimizing your React components.
Why Use React DevTools?
How to Install and access React DevTools
Ctrl+Shift+I
or Cmd+Option+I
), and you’ll see a React tab if you’re on a React application.Using React DevTools
Let’s explore a few common scenarios where React DevTools can be helpful.
1. Inspecting Component Hierarchies
With React DevTools, you can visualize the tree structure of your components, making it easier to understand how they are nested and interact with each other.
For example, if your app renders incorrectly, you can inspect the hierarchy to confirm that the right components are being rendered where you expect them.
2. Debugging State and Props
React DevTools allows you to select any component and inspect its state and props.
Imagine a counter component where the count isn't updating. Using React DevTools, you can check if the state.count is changing correctly when the button is clicked. With DevTools, you can verify if count is being updated or if there’s an issue in the click handler.
3. Identifying Performance Bottlenecks
The Profiler tab in React DevTools helps you measure the rendering performance of your app.
A common use case is when your app feels sluggish, you can use the Profiler to check which components are re-rendering unnecessarily and optimize them.
Best Practices for Using React DevTools
Here is how the React DevTool (Component tab) looks like when running a React application:
Think of React DevTools as a magnifying glass for your code. Instead of guessing why something is broken or slow, you can zoom in and see the details.
These practices may seem small, but they create a strong foundation for building scalable React applications.
Build and keep track of your application's structure and performance via React DevTools.
Happy coding! 🚀
.....
.....
.....