DEV Community

Cover image for 🌱 Building [clean] reusable React components
Programming with Shahan
Programming with Shahan

Posted on • Edited on

🌱 Building [clean] reusable React components

What are reusable React components? They are independent pieces of code that can be reused throughout your website to save you time and effort.

They can be anything from simple buttons to complex forms. πŸ¦‹

πŸ™Ž Why Use Clean Reusable Components?

As your website grows, you can easily add new features by combining existing components. This makes your code more scalable and adaptable.

Plus, you can use your clean reusable code in future projects without writing it again from scratch. Any doubt? keep reading...πŸ“–


🏭 How to Make Clean Reusable React Components

Image OF HOW TO BUILD CLEAN REUSABLE COMPONENT IN REACT

Here are the two most important things to keep in mind when creating clean reusable React components:

1. 🩼 Avoid Side Effects

Don't put logic that interacts with external data (like making API calls) directly inside a reusable component. Instead, pass this logic as props to the component.

For example, if a button does more than just looking pretty, like fetching data from the internet, it might not be reusable. πŸ‘Ž

πŸͺ§ This is a reusable button component. But it lacks best practices.

I will show you why in the example section.

// This is a reusable button component (bad practice!)
const Button = () => {
  return (
    <button> Click Me </button>
  );
}
Enter fullscreen mode Exit fullscreen mode

2. πŸ—ƒοΈ Use Props

Props are arguments you pass to a component to customize its behavior and appearance. This allows you to use the same component for different purposes.

// This is a button component that can change its color
const Button = ({ color }) => {
  return (
    <button style={{ backgroundColor: color }}> Click Here </button>
  );
}
Enter fullscreen mode Exit fullscreen mode

This is still a bad practice because you have a fixed label called "Click Here". If you want to change the text on your button to, let's say: "Sign Up", then you would have to go back to the button component and make that change. πŸ™Ž

That means every time you want to use a different text, we'd have to go back and edit the code. In other words, it's NO longer reusable. πŸͺ¦

πŸ’ͺ Challenge: So what's the solution?
You already have the answer. But if you don't, I am going to show you in the example section.

🌴 Hint: Think about how you might want to use the component in different situations and design it to be flexible and adaptable.

πŸƒExamples of Reusable React Components

Here are some common examples of reusable React components, along with some code examples to get you started:

Buttons

Basic buttons with different styles and functionalities.

// Button component
import React from "react";

const Button = ({ color, label, onClick }) => {
  return (
    <button
      className={`padding-2 shadow-none hover:shadow background-light-${color} hover:background-dark-${color}`}
      onClick={onClick}
    >
      {label}
    </button>
  );
};

export default Button;

// Using the Button component
<Button color="blue" label="Click Here" onClick={() => console.log("Button clicked!")} />
Enter fullscreen mode Exit fullscreen mode

As you can see, I did not write "Click Here" in the button component. I want to make my button reusable, and thus it doesn't know anything about custom styles or texts.

So, I passed them as props (i.e., color, label, and onClick) to change them in the future without touching the original button components. Hope that makes it clear.

πŸͺœSolution: You need to pass each functionality as props in the reusable component.

Navbars

Navigation bars that provide consistent navigation across your website.

// Navbar component
import React from "react";

const Navbar = ({ isLoggedIn }) => {
  return (
    <div className="navbar">
      <div className="navbar-container">
        <div className="navbar-logo">
          <img src={logo} alt="logo" />
        </div>
        <div className="navbar-links">
          <a href="/">Home</a>
          <a href="/about">About</a>
          <a href="/contact">Contact</a>
          {isLoggedIn ? (
            <a href="/profile">Profile</a>
          ) : (
            <a href="/login">Login</a>
          )}
        </div>
      </div>
    </div>
  );
};

export default Navbar;

// Using the Navbar component
<Navbar isLoggedIn={true} />
Enter fullscreen mode Exit fullscreen mode

As you can see, I passed <Navbar isLoggedIn={true} />

This line triggers the Navbar component and passes the isLoggedIn prop with a value of true, indicating the user is logged in. This will display the "Profile" link and hide the "Login" link.

Similar to the button component, the Navbar component is reusable and accepts props to customize its behavior. Perfect! πŸ‘

πŸ€™ Why API Calls in a Button Component is a Bad Practice

Now, you understand everything about reusable components in React.

Let's dig deeper by solving a complex problem.

Consider the scenario where you have a button that does an API call. The code for the button component can be the following:

import React from "react"; 
import doAPICall from "../api"

const SaveButton  = () => {
  return (
    <button
      onClick={() => {
        doAPICall();
      }}
    >
      Save
    </button>
  );
}

export default SaveButton
Enter fullscreen mode Exit fullscreen mode

It is quite clear that you can’t reuse the above button in_ multiple_ places as this button component contains a side-effect (doAPICall()) inside it. ⚠️

You can make this component reusable. First, you'll have to extract the side-effect and pass that as a prop to the button component like this:

const App = () =>  {
  function doAPICall() {
    // Does an API call to save the current state of the app.
  }

  return (
    <div>
      <SaveButton onClick={doAPICall}/>
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

The button component should look like this:

const SaveButton  = ({
  onClick
}) => {
  return (
    <button
      onClick={onClick}
    >
      Save
    </button>
  );
}
Enter fullscreen mode Exit fullscreen mode

As you can see, the above button can now be reused anywhere you want to save data with the click of a button. The button can now be used like this in multiple places: πŸ—οΈ

const App = () =>  {
  function saveUser() {
    // Does an API call to save the user.
  }

  function saveProject() {
    // Does an API call to save the project.
  }

  return (
    <div>
      <SaveButton onClick={saveUser}/>
      <SaveButton onClick={saveProject}/>
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

You can also make the button component more reusable by using a prop to control the label:

const App = () =>  {
  function saveUser() {
    // Does an API call to save the user.
  }

  function saveProject() {
    // Does an API call to save the project.
  }

  return (
    <div>
      <SaveButton onClick={saveUser} label="Save user"  />
      <SaveButton onClick={saveProject} label="Save project" />
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

The button component should look like this:

const SaveButton  = ({
  onClick,
  label
}) => {
  return (
    <button
      onClick={onClick}
    >
      {label}
    </button>
  );
}
Enter fullscreen mode Exit fullscreen mode

🚨 Early Bird Offer 🚨

If you’re serious about mastering clean code and taking your web development career to the next level, then this book is for you. Grab Clean Code Zero to One today with a 50% discount using the code "earlybird" β€” only for the first 50 developers! Plus, enjoy a 30-day money-back guarantee β€” no risk, all reward.

πŸ‘ Conclusion

Congratulations! You've successfully learned how to build clean reusable React components.

Remember, reusable components are the building blocks of robust React development. By practicing clean React components, you can build cleaner, more efficient, and more maintainable React applications.

The more you practice, the better you'll become at identifying opportunities to use them in your projects!

πŸ“– Read More: 10 bulletproof rules for writing clean code

Thank you for taking the time to read this article. Until next time.. Keep learning and you can follow me on 𝕏 for the latest updates on programming and clean code.

Top comments (1)

Collapse
 
oussamabouyahia profile image
Oussama Bouyahia

yes it is very useful ,in my code I am using always a reusable button component , you can add another useful isDisable props , so button will be able only after validation.