Open-Closed Principle (OCP) in React: Building Extensible Components

Learn how to apply the Open-Closed Principle in React to build components that are easy to extend without modifying core logic. Enhance scalability, maintainability, and flexibility in your React apps.

deepika beniwal

3 months ago

open-closed-principle-ocp-in-react-building-extensible-components

The Open-Closed Principle—a key tenet of SOLID software design—states that software entities should be open for extension but closed for modification. In the context of React, this means designing components that are flexible and extensible without needing to change their internal logic every time a new requirement comes along.

When followed correctly, OCP enables you to create scalable, testable, and maintainable React applications.

1. What is the Open-Closed Principle?

Definition:
Your code should allow for extensions (new behaviors or features) without requiring modification to existing source code.

Why it matters:
Prevents bugs introduced by editing working code
Supports cleaner, modular component design
Encourages reuse and consistent scalability
Reduces long-term tech debt in large codebases

2. How OCP is Commonly Violated in React

  • Hardcoded Logic in Components:
    Components that bake in business rules make it harder to adapt to new use cases.

  • Changing Components for Each New Feature:
    Repeated edits for every new variant or behavior increase complexity and regressions.

  • Growing Complexity Over Time:
    As more conditions are added, components become harder to read, maintain, and test.

3. OCP-Friendly Practices in React

  • Favor Composition Over Conditionals:
    Pass behaviors via props or use children as extensibility points instead of adding logic directly.

  • Build Reusable Base Components:
    Create generalized, configurable components that can be extended, not rewritten.

  • Use Custom Hooks:
    Separate logic from UI. This keeps components focused and allows logic to be reused or extended easily.

  • Externalize Styling and Configuration:
    Use themes, style tokens, or config objects to manage variants and styling, so changes don’t touch the component logic.

4. Real-World Example: Refactoring a Button Component

Before (OCP Violation – Logic tied to component):

jsx

const Button = ({ variant, ...restProps }) => {

let classes = "border rounded-md";

if (variant === "primary") {

classes += " bg-primary text-white";

} else if (variant === "secondary") {

classes += " bg-secondary text-white";

}

return <button className={classes} {...restProps} />;

};

Every time you add a new variant, you have to modify this component.

After (OCP-Compliant – Externalized theme):

jsx

const Button = ({ variant, ...restProps }) => {

const { theme: { button: theme } } = useTheme();

const classes = theme.variant[variant];

return <button className={classes} {...restProps} />;

};

Now, to support a new variant, you simply update the theme—no need to touch the component.

Final Thoughts

Applying the Open-Closed Principle in your React architecture helps you future-proof your components. It allows your UI to evolve while keeping core code stable. By embracing composition, configuration, and separation of concerns, your components become easier to extend—and harder to break.

Over to You!

Have you applied OCP in your React projects?
Which patterns or practices helped you make your components more extensible?
Let’s swap ideas in the comments! 🚀