ROBBY HOOVER
Header Photo
How (Not) To Use Inheritence with React
And Most Other Component-Based Frameworks
March 29, 2023

What is Inheritance?

Inheritance is a technique, most commonly found in object-oriented programming, that allows for a new class to be based on an existing class, inheriting its attributes and behaviors. This facilitates code reuse, reduces redundancy, and enhances code modularity. The new class is called a derived class, and the existing class is the base class.

For example, we could have a base class, known as "Animal", which contains attributes such as a 'Name' and a behavior such as 'Eat'. We could then create a derived class, known as 'Dog'. Within the 'Dog' class, we can create a 'Bark' behavior. Now, with a new instance of Dog, we can 'Bark', but we can also access all the attributes and behaviors inherited from the Animal class.

The relationships and hiearchy can get much more complex than this, but this is all you need to know for the purposes of this post.

The relationships and hierarchy can get much more complex than this, but this is all you need to know for our purposes.

Why You Shouldn't Use Inheritance with React

Despite supporting some object-oriented programming concepts, React is primarily a functional programming library. Functional programming is a programming paradigm that emphasizes the use of pure functions, immutable data, and functional composition to write programs that are concise, modular, and easy to reason about.

In functional programming, inheritance is not commonly used because it introduces tight coupling (heavy dependency between classes) and can lead to code that is difficult to reason about and test. Instead, functional programming emphasizes the use of pure functions and function composition, which enable the creation of modular and reusable code without the need for complex class hierarchies.

Instead, React favors a principle known as composition.

Use Composition Instead

The creators of React suggest that developers who are using React use 'composition' instead of inheritance.

React prefers composition over inheritance because it allows for more flexible and modular code, making it easier to build and maintain complex UI components. Composition involves building components from smaller, reusable pieces, rather than relying on inheritance to create complex class hierarchies. Composition is more flexible than inheritance because it allows components to be composed in different ways to achieve different functionalities. Composition also helps to separate the concerns of different parts of the code, making it easier to understand and modify. This promotes better organization and maintainability of code.

Composition is a different approach, in which objects are composed of other objects, rather than inheriting from a common superclass. This allows for greater flexibility and modularity in program design, as objects can be composed of different combinations of other objects to provide the desired behavior. In general, composition is preferred over inheritance in modern programming because it allows for looser coupling and greater separation of concerns.

Types of Composition

The creators of react define two types of composition that we might have to use while developing our applications. Containment and Specialization.

Specialization

Sometimes we think about components as being “special cases” of other components. For example, we might say that Dog is a special case of Animal.

In React, this is achieved by composing a more 'specific' component that renders a preconfigured version of a more 'generic' component.

Specialization Diagram
const Animal = (species, name, vocalization) =>{
const [species, setSpecies] = useState(species)
const [name, setName] = useState(name)
const [vocalization, setVocalization] = useState(name)

const eat = () => { 
console.log(`${name} the ${species} is eating`)
}

const vocalize = () = { 
console.log(`the ${species} is ${vocalization}ing`)
}
}

const Dog = () => {
return Animal ('Dog', 'Fido', 'Bark')
}

const myDog = new Dog();
myDog.eat()     // "The Dog is Barking"
myDog.vocalize()     // "Fido the Dog is eating"

As you can see, our Dog component doesn't do much on its own, it simply returns an Animal Component that has already been configured with the proper parameters to indicate that it is indeed a dog and consequently barks and is named Fido.

This relationship is sometimes also called the "is-a" relationship, where the specialized component "is-a" more specific version of the base component. Specialization composition is often used to create more specific components by modifying more generic ones, allowing for a more flexible and reusable codebase.

Containment

Some components don’t know what their children will be ahead of time. This is especially common for components like Navigation or Modal that represent generic “boxes”.

In React, this is remedied by utilizing the special children prop to pass child elements directly to the component's output. This lets other components pass arbitrary children to them by nesting the JSX, similar to how you pass the text you want displayed within a button into the button element. You just stick the child elements between the angled brackets.

This is also known as "has-a" composition, in which an object or component contains other objects or components as its parts. In other words, a composite object "has-a" collection of other objects or components that are contained within it.
function Wrapper(props) {
return (
<div className="Wrapper">
{props.children}
</div>
);
}

function App() {
return (
<div className="App">
<Wrapper>
<h1>Hello, world!</h1>
<p>Welcome to my app.</p>
</Wrapper>
</div>
);
}

This is also known as "has-a" composition, in which an object or component contains other objects or components as its parts. In other words, a composite object "has-a" collection of other objects or components that are contained within it.

In general, containment composition is often used to create complex UI structures and layouts by combining smaller, reusable components together.

Parting Words

In summary, inheritance is a mechanism in object-oriented programming where a class can inherit properties and methods from a parent class, allowing it to reuse code and build upon existing behavior. Composition, on the other hand, is a mechanism for combining simpler components or parts to create more complex behavior.

Within the realm of composition, specialization allows us to create general components with a loosely defined structure that we can then use to create specialized components. Containment, on the other hand, allows us to send anything we want to it, so the component can take many different types of input.

Leave a Comment


Comments

Collection: Loading...

No Comments Yet!

Read More!

© Robby Hoover 2022