DEV Community

Cover image for Liskov Substitution Principle in React
Mikhael Esa
Mikhael Esa

Posted on • Updated on

Liskov Substitution Principle in React

L (Liskov Substitution Principle)

Objects of a superclass should be replaceable with objects of its subclasses without breaking the application

Spiderman pointing gif

In React, the Liskov Substitution Principle (LSP) underscores the importance of allowing child components to seamlessly replace their parent components while maintaining the same interface and functionality. This enables developers to compose complex user interfaces by substituting components, promoting code reusability and maintainability.

By adhering to LSP in React, developers create a hierarchy of interchangeable components. This means that base components and their derived counterparts can be swapped without affecting the application's core functionality, simplifying development, enhancing code readability, and facilitating better component behavior understanding. In essence, Liskov Substitution in React encourages the creation of a flexible and cohesive component structure for building robust and maintainable user interfaces.

Confused gif

The implementation is actually not as sophisticated as the explanation. Don't believe me? See for yourself 😉.



const DangerButton = () => {
  return <div>Danger</div>;
};


Enter fullscreen mode Exit fullscreen mode

So we want to create a DangerButton component but a button functionality couldn't be replaced by a div so this violates the principle.

What we should do instead is just return a button like this



const DangerButton = () => {
  return <button>Danger</button>;
};


Enter fullscreen mode Exit fullscreen mode

This looks better but it's not enough. We also need to inherit all the functionalities of the button itself.



interface IDangerButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
  children: ReactNode
  // Your extra props if you have
}

const DangerButton = ({ children, ...props }: IDangerButtonProps) => {
  return <button {...props} className="danger">{children}</button>;
};


Enter fullscreen mode Exit fullscreen mode

Now we have inherited all of the attributes of the button and we pass the attributes to the new button. This way, any instance of DangerButton can still be used in place of an instance of Button without changing the program’s behavior and complying with the Liskov Substitution Principle.

What's next?

Let's not stop here since there are 2 more principles left to learn in SOLID which I will cover in the next article so stay tuned.

Dadah~ 👋

Top comments (2)

Collapse
 
luisrodriguez profile image
Luis David Rodriuez Valades

I like the way you adapted this principle, it is a great article!
I only think this principle couldn't apply fully to react, it is most focused on OOP and real Inheritance, react is more oriented to functional programming.
Either way really nice article!!

Collapse
 
equiman profile image
Camilo Martinez • Edited

In those scenarios, it will be better to use React.ComponentPropsWithoutRef<"button"> instead of ButtonHTMLAttributes<HTMLButtonElement> ?

Or is it only an alternative way of doing the same?