REACT Reusability

Reusability in React helps reduce code duplication, improve maintainability, and enhance scalability. By breaking down components into smaller, reusable units, you can build apps faster and make changes more efficiently.

 

1. Reusable Components

Example: A Reusable Button Component

Instead of creating separate buttons for different parts of your app, use a reusable component:

// components/Button.js
const Button = ({ text, onClick, type = "button", className = "" }) => {
  return (
    <button onClick={onClick} type={type} className={`btn ${className}`}>
      {text}
    </button>
  );
};

export default Button;

Usage:

import Button from "./components/Button";

const App = () => (
  <div>
    <Button text="Click Me" onClick={() => alert("Clicked!")} className="btn-primary" />
    <Button text="Submit" type="submit" className="btn-success" />
  </div>
);

Benefits: Less duplication, easier styling, and flexible usage.

 

2. Reusable Form Components

Instead of duplicating form inputs, create a generic input component:

// components/InputField.js
const InputField = ({ label, type = "text", value, onChange }) => {
  return (
    <div>
      <label>{label}</label>
      <input type={type} value={value} onChange={onChange} />
    </div>
  );
};

export default InputField;

Usage:

import InputField from "./components/InputField";
import { useState } from "react";

const Form = () => {
  const [email, setEmail] = useState("");

  return (
    <form>
      <InputField label="Email" type="email" value={email} onChange={(e) => setEmail(e.target.value)} />
    </form>
  );
};

Reusability: Works for different input types like text, email, password, etc.

 

3. Higher-Order Components (HOCs)

HOCs allow code reusability by wrapping components with additional functionality.

Example: A withAuth HOC for Authentication

// hoc/withAuth.js
const withAuth = (WrappedComponent) => {
  return (props) => {
    const isAuthenticated = true; // Example logic
    return isAuthenticated ? <WrappedComponent {...props} /> : <p>Please login</p>;
  };
};

export default withAuth;

Usage:

import withAuth from "./hoc/withAuth";

const Dashboard = () => <h1>Welcome to Dashboard</h1>;

export default withAuth(Dashboard);

Reusability: Apply authentication logic to multiple pages without duplicating it.

 

4. Render Props

Render props allow you to share code between components using a function as a prop.

Example: A Mouse Tracker Component

// components/MouseTracker.js
const MouseTracker = ({ render }) => {
  const [position, setPosition] = useState({ x: 0, y: 0 });

  const handleMouseMove = (event) => {
    setPosition({ x: event.clientX, y: event.clientY });
  };

  return <div onMouseMove={handleMouseMove}>{render(position)}</div>;
};

export default MouseTracker;

Usage:

import MouseTracker from "./components/MouseTracker";

const App = () => (
  <MouseTracker render={(position) => <p>Mouse position: {position.x}, {position.y}</p>} />
);

Reusability: Share logic between multiple components with different UI needs.

 

5. Custom Hooks

Custom Hooks allow you to reuse logic across multiple components without affecting their structure.

Example: A Custom Hook for Fetching Data

// hooks/useFetch.js
import { useState, useEffect } from "react";

const useFetch = (url) => {
  const [data, setData] = useState(null);

  useEffect(() => {
    fetch(url)
      .then((res) => res.json())
      .then((data) => setData(data));
  }, [url]);

  return data;
};

export default useFetch;

Usage:

import useFetch from "./hooks/useFetch";

const Users = () => {
  const users = useFetch("https://jsonplaceholder.typicode.com/users");

  return (
    <ul>
      {users?.map((user) => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  );
};

Reusability: Use useFetch anywhere without rewriting the same logic.

6. React Context for Global State Management

Avoid prop drilling by using React Context to share state across components.

Example: A Theme Context

// context/ThemeContext.js
import { createContext, useState } from "react";

export const ThemeContext = createContext();

export const ThemeProvider = ({ children }) => {
  const [theme, setTheme] = useState("light");

  return (
    <ThemeContext.Provider value={{ theme, setTheme }}>
      {children}
    </ThemeContext.Provider>
  );
};

Usage:

import { useContext } from "react";
import { ThemeContext } from "./context/ThemeContext";

const ThemeToggle = () => {
  const { theme, setTheme } = useContext(ThemeContext);
  return (
    <button onClick={() => setTheme(theme === "light" ? "dark" : "light")}>
      Toggle Theme
    </button>
  );
};

Reusability: Share state globally without prop drilling.

 

7. Utility Functions for Reusability

Move common functions to a separate utils folder.

Example: A Utility Function for Date Formatting

// utils/formatDate.js
export const formatDate = (date) => new Date(date).toLocaleDateString();

Usage:

import { formatDate } from "./utils/formatDate";

console.log(formatDate("2025-01-29")); // Output: 1/29/2025

Reusability: Avoid duplicating helper functions across components.