Frontend DevelopmentIntermediate15 min read

How to Design Reusable React Components Across Projects (Practical Guide)

Abhishek Madoliya

Abhishek Madoliya

Learn advanced React patterns including compound components, render props, and hooks composition

Prerequisites

  • Basic React knowledge
  • Understanding of hooks
  • ES6+ JavaScript

1. Why Creating reusable components in react Matter More Than You Think

Let me start with something honest.

Anyone can write a React component that works. Very few people write components that can be reused without pain.

Example of reusable React component structure
A simple example showing how reusable React components are structured.

When you work on real projects—or when someone reviews your code in an interview—they are not impressed by how many components you wrote. They care about how well you designed them.

  • You don't rewrite the same UI again and again
  • Your code stays easier to understand
  • Changes don't break multiple files
  • Other developers can use your components easily
      
      // Non-reusable component
      function Button() {
        return <button>Submit</button>;
      }
      
      // Reusable component
      function Button({ label }) {
        return <button>{label}</button>;
      }
      
      

React reusable components show that you think ahead, not just code for today.


2. The Most Common Mistake Beginners Make

Almost everyone makes this mistake at the beginning (including me).

You build a component with:

  • Hardcoded text
  • Fixed styles
  • Logic mixed with UI
  • Only one use case in mind

It works perfectly... for that one page.

      
      function ProfileCard() {
        return (
          <div>
            <h2>Admin User</h2>
            <p>Access granted</p>
          </div>
        );
      }
      
      

Later, when you need the same component with different data, you copy-paste it. Now you have duplicates.

Reusable components avoid this by not assuming too much.


3. Think of Components Like Functions

Here's a simple way to think about React components.

A good component is like a good function:

  • It takes inputs
  • It returns an output
  • It does one job clearly

In React terms:

  • Inputs = props
  • Output = UI
      
      function Greeting({ name }) {
        return <h1>Hello, {name}!</h1>;
      }
      
      

Before writing JSX, ask yourself what should change and what should stay the same. This keeps your components clean.


4. Designing Props the Right Way

Props are the heart of reusability.

A reusable component should receive data from the outside and avoid making decisions that the parent should make.

Bad habit:

      
      function Button() {
        return <button>Save</button>;
      }
      
      

Better habit:

      
      function Button({ text, onClick }) {
        return <button onClick={onClick}>{text}</button>;
      }
      
      

Name props clearly. Someone reading your component should understand how to use it without guessing.

If props feel confusing or too many, it usually means the component is doing too much.


5. Keep Logic and UI Separate When Possible

When a component handles everything at once—data, logic, and UI—it becomes hard to reuse.

A simple improvement is to separate what the component does from how it looks.

      
      // Logic
      function useCounter() {
        const [count, setCount] = React.useState(0);
        return { count, increment: () => setCount(count + 1) };
      }
      
      // UI
      function CounterUI({ count, onIncrement }) {
        return (
          <button onClick={onIncrement}>
            Count: {count}
          </button>
        );
      }
      
      

6. Designing Components That Work in Different Projects

Ask yourself one simple question:

Would this component still make sense in another project?

Avoid project-specific assumptions inside components.

      
      // Bad: project-specific
      function UserCard() {
        return <div>Admin Panel User</div>;
      }
      
      // Better: reusable
      function Card({ children }) {
        return <div className="border p-4">{children}</div>;
      }
      
      

7. Controlled vs Uncontrolled Components

A controlled component gets its value from the parent.

      
      function Input({ value, onChange }) {
        return <input value={value} onChange={onChange} />;
      }
      
      

An uncontrolled component manages its own state.

      
      function Input() {
        const ref = React.useRef();
        return <input ref={ref} />;
      }
      
      

Controlled components are usually easier to reuse and test.


8. Avoiding Prop Drilling Without Overthinking

Prop drilling happens when props are passed through many layers.

      
      function App() {
        return <Parent user="Alex" />;
      }
      
      function Parent({ user }) {
        return <Child user={user} />;
      }
      
      function Child({ user }) {
        return <p>Hello {user}</p>;
      }
      
      

Before using Context or libraries, see if structure can be simplified.


9. Use Composition Instead of Conditions

Too many if conditions reduce flexibility.

      
      function Modal({ children }) {
        return <div className="p-4 border">{children}</div>;
      }
      
      // Usage
      <Modal>
        <h2>Title</h2>
        <p>Content here</p>
      </Modal>
      
      

Composition keeps components simple and reusable.


10. Reusability vs Overengineering

Not everything needs to be reusable.

      
      // Overengineering example
      function Button({ size, color, variant, radius }) {
        // Too many options for no real use
      }
      
      

Start simple. Generalize only when reuse appears.


11. How to Check If a Component Is Reusable

  • Can text change without editing the component?
  • Can behavior change via props?
  • Does it avoid hardcoded logic?
      
      function Button({ label, onClick }) {
        return <button onClick={onClick}>{label}</button>;
      }
      
      

12. Folder Structure That Supports Reuse

Clear folders make reusable components obvious.

      
      components/
        common/
          Button.jsx
          Card.jsx
        features/
          Dashboard.jsx
      
      

13. Interview Questions About Reusability

Interviewers often ask simple questions.

      
      // Example answer structure:
      "I keep components flexible by passing data via props,
      separating logic from UI, and avoiding hardcoded values."
      
      

Clear explanation matters more than fancy terms.


14. Refactoring a Non-Reusable Component

      
      // Before
      function Alert() {
        return <div>Error occurred</div>;
      }
      
      // After
      function Alert({ message }) {
        return <div>{message}</div>;
      }
      
      

Small changes make a big difference.


15. Final Checklist

  • Clear props
  • Minimal state
  • No unnecessary dependencies
  • Easy to explain

16. Final Thoughts

Reusable components are about clarity, not perfection.

Build → Refactor → Improve. That's how real frontend developers grow.

#React#JavaScript#Frontend#Patterns
How to Design Reusable React Components Across Projects | CloudVyn