Zum Hauptinhalt springen
tsecurity.de LIVE
Echtzeit-Radar & Feeds
Alle RSS Feeds
👥 Community & Social
Sichere ProgrammierungWhy Your AI Chatbot Forgets Everything — And How to Fix It(23.09.2026 um 16:30 Uhr)
Sichere ProgrammierungHow Jev Works: The Logit Trick Behind TypeSafe's System One Model(23.09.2026 um 16:32 Uhr)
Sichere ProgrammierungInterfaces in Java, Explained(23.09.2026 um 16:36 Uhr)
Sichere ProgrammierungWhat Is AI Observability? A Definition for Engineers(23.09.2026 um 16:42 Uhr)
Sichere ProgrammierungSynth-OOP: An Object-Oriented Language Where Operators Become Methods(23.09.2026 um 16:44 Uhr)
Sichere ProgrammierungAI Can Remember Everything. That's Exactly the Problem.(23.09.2026 um 16:44 Uhr)
Sichere ProgrammierungGas Optimization Audit: Curve DEX(23.09.2026 um 16:45 Uhr)
Sichere ProgrammierungDoes finally Run Before return? What javac Actually Does(23.09.2026 um 16:49 Uhr)
Sichere ProgrammierungWhy Your AI Chatbot Forgets Everything — And How to Fix It(23.09.2026 um 16:30 Uhr)
Sichere ProgrammierungHow Jev Works: The Logit Trick Behind TypeSafe's System One Model(23.09.2026 um 16:32 Uhr)
Sichere ProgrammierungInterfaces in Java, Explained(23.09.2026 um 16:36 Uhr)
Sichere ProgrammierungWhat Is AI Observability? A Definition for Engineers(23.09.2026 um 16:42 Uhr)
Sichere ProgrammierungSynth-OOP: An Object-Oriented Language Where Operators Become Methods(23.09.2026 um 16:44 Uhr)
Sichere ProgrammierungAI Can Remember Everything. That's Exactly the Problem.(23.09.2026 um 16:44 Uhr)
Sichere ProgrammierungGas Optimization Audit: Curve DEX(23.09.2026 um 16:45 Uhr)
Sichere ProgrammierungDoes finally Run Before return? What javac Actually Does(23.09.2026 um 16:49 Uhr)
Intelligence View
⚡ tsecurity.de Intelligence

Composition vs Inheritance: Why React Chose the "Has-A" Over "Is-A" Relationship

If you've learned object-oriented programming in languages like Java or C++, you've been taught that inheritance is the way to reuse code. Create a base class, extend it, override methods — it's the OOP way. But React's official d…

0
↗ Quelle (dev.to)
Reagiere als Erste:r — dein Feedback zählt!

If you've learned object-oriented programming in languages like Java or C++, you've been taught that inheritance is the way to reuse code. Create a base class, extend it, override methods — it's the OOP way.



But React's official documentation says something surprising: "At Facebook, we use React in thousands of components, and we haven't found any use cases where we would recommend creating component inheritance hierarchies."



Why? Because composition is more flexible, more explicit, and easier to maintain than inheritance.






The Golden Rule



In JavaScript and React, prefer composition ("has-a" relationships) over inheritance ("is-a" relationships). Build complex components by combining simpler ones, not by creating deep class hierarchies.



In simpler terms: Instead of saying "Button is-a Component," say "Button has-a label and has-a onClick handler."



Let's understand why this matters and how to apply it.









Part 1: Inheritance vs Composition in JavaScript






Inheritance: The "Is-A" Relationship



Inheritance models an "is-a" relationship using class hierarchies.




class Animal {
constructor(name) {
this.name = name;
}

eat() {
console.log(`${this.name} is eating`);
}

sleep() {
console.log(`${this.name} is sleeping`);
}
}

class Dog extends Animal {
bark() {
console.log(`${this.name} barks`);
}
}

class Cat extends Animal {
meow() {
console.log(`${this.name} meows`);
}
}

const dog = new Dog('Buddy');
dog.eat(); // "Buddy is eating"
dog.bark(); // "Buddy barks"






The relationship: Dog is-a Animal, Cat is-a Animal.



Looks good so far, right? Now let's add more behavior...









The Problem with Deep Inheritance



What if we want:




  • A Robot that can walk() but doesn't need eat() or sleep()

  • A FlyingDog that can bark() and fly()

  • A SwimmingRobot that can walk() and swim()



Inheritance solution (becomes messy):




class Animal {
eat() {}
sleep() {}
}

class WalkingAnimal extends Animal {
walk() {}
}

class FlyingAnimal extends Animal {
fly() {}
}

// Problem: Dog needs both walking AND barking
class Dog extends WalkingAnimal {
bark() {}
}

// Problem: FlyingDog can't extend both Dog and FlyingAnimal!
// JavaScript doesn't support multiple inheritance
class FlyingDog extends ??? {
//
Stuck!
}






The issue: You're forced into a rigid hierarchy. You can't mix and match behaviors.









Composition: The "Has-A" Relationship



Composition models a "has-a" relationship by combining smaller objects.




// Behavior objects (composable)
const canEat = (state) => ({
eat: () => console.log(`${state.name} is eating`)
});

const canSleep = (state) => ({
sleep: () => console.log(`${state.name} is sleeping`)
});

const canBark = (state) => ({
bark: () => console.log(`${state.name} barks`)
});

const canFly = (state) => ({
fly: () => console.log(`${state.name} flies`)
});

// Compose behaviors
const createDog = (name) => {
const state = { name };
return {
...canEat(state),
...canSleep(state),
...canBark(state)
};
};

const createFlyingDog = (name) => {
const state = { name };
return {
...canEat(state),
...canSleep(state),
...canBark(state),
...canFly(state) // Easy to add!
};
};

const dog = createDog('Buddy');
dog.eat(); // "Buddy is eating"
dog.bark(); // "Buddy barks"

const flyingDog = createFlyingDog('Super Buddy');
flyingDog.bark(); // "Super Buddy barks"
flyingDog.fly(); // "Super Buddy flies"






The relationship: Dog has the ability to eat, sleep, and bark. FlyingDog has those abilities plus flying.



Key Advantage: You can mix and match behaviors freely without rigid hierarchies.









Part 2: Why React Prefers Composition



React's component model is built around composition, not inheritance.






Inheritance in React (The Old Way)



In early React, you might see:




class BaseButton extends React.Component {
handleClick = () => {
console.log('Base button clicked');
}

render() {
return <button onClick={this.handleClick}>Base</button>;
}
}

class PrimaryButton extends BaseButton {
handleClick = () => {
console.log('Primary button clicked');
}

render() {
return (
<button className="primary" onClick={this.handleClick}>
Primary
</button>
);
}
}






Problems:




  1. Tight coupling — PrimaryButton is tightly bound to BaseButton's implementation

  2. Hard to modify — Changing BaseButton might break PrimaryButton

  3. Limited reuse — Can't easily combine behaviors from multiple base classes

  4. Not composable — Can't use a PrimaryButton inside a BaseButton









Composition in React (The Modern Way)



Instead of extending, compose:




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

function PrimaryButton({ onClick, children }) {
return (
<Button className="primary" onClick={onClick}>
{children}
</Button>
);
}

function DangerButton({ onClick, children }) {
return (
<Button className="danger" onClick={onClick}>
{children}
</Button>
);
}






Advantages:




  • Flexible — Easy to compose buttons with different styles

  • Reusable — Button is a simple, focused component

  • Testable — Each component can be tested independently

  • Explicit — Clear what props each component accepts









Part 3: Composition Patterns in React






Pattern 1: children Prop (Containment)



The most basic composition pattern is using the children prop:




function Card({ children }) {
return <div className="card">{children}</div>;
}

function App() {
return (
<Card>
<h1>Title</h1>
<p>Description</p>
</Card>
);
}






Key Point: Card doesn't know what its children are — it just renders them. This makes it maximally reusable.









Pattern 2: Named Slots (Multiple Composition Points)



For more complex layouts, use named props instead of just children:




function Dialog({ title, content, actions }) {
return (
<div className="dialog">
<div className="dialog-title">{title}</div>
<div className="dialog-content">{content}</div>
<div className="dialog-actions">{actions}</div>
</div>
);
}

function App() {
return (
<Dialog
title={<h1>Confirm Delete</h1>}
content={<p>Are you sure?</p>}
actions={
<>
<button>Cancel</button>
<button>Delete</button>
</>
}
/>
);
}






Advantages:




  • Clear structure (title, content, actions)

  • Each slot can contain any React element

  • More controlled than a single children prop









Pattern 3: Specialization (Specific Cases of Generic Components)



Create specific versions of generic components:




function Dialog({ title, children }) {
return (
<div className="dialog">
<h1>{title}</h1>
<div>{children}</div>
</div>
);
}

function WelcomeDialog() {
return (
<Dialog title="Welcome">
<p>Thank you for visiting our spacecraft!</p>
</Dialog>
);
}

function ConfirmDialog() {
return (
<Dialog title="Confirm">
<p>Are you sure?</p>
<button>Yes</button>
<button>No</button>
</Dialog>
);
}






Key Point: WelcomeDialog and ConfirmDialog are specialized versions of the generic Dialog component.









Pattern 4: Higher-Order Components (HOCs)



HOCs are functions that take a component and return a new component with additional props or behavior:




// HOC that adds loading state
function withLoading(Component) {
return function WithLoadingComponent({ isLoading, ...props }) {
if (isLoading) {
return <div>Loading...</div>;
}
return <Component {...props} />;
};
}

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

const UserListWithLoading = withLoading(UserList);

function App() {
const [users, setUsers] = useState([]);
const [isLoading, setIsLoading] = useState(true);

return <UserListWithLoading isLoading={isLoading} users={users} />;
}






Use case: Adding cross-cutting concerns (loading, error handling, authentication) to multiple components.









Pattern 5: Render Props



A component with a render prop takes a function as a child:




function MouseTracker({ render }) {
const [position, setPosition] = useState({ x: 0, y: 0 });

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

window.addEventListener('mousemove', handleMouseMove);
return () => window.removeEventListener('mousemove', handleMouseMove);
}, []);

return render(position);
}

function App() {
return (
<MouseTracker
render={({ x, y }) => (
<div>
Mouse position: {x}, {y}
</div>
)}
/>
);
}






Use case: Sharing stateful logic between components without HOCs.



Modern alternative: Custom hooks (see below).









Pattern 6: Custom Hooks (Modern Composition)



Custom hooks are the modern way to compose logic:




function useMousePosition() {
const [position, setPosition] = useState({ x: 0, y: 0 });

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

window.addEventListener('mousemove', handleMouseMove);
return () => window.removeEventListener('mousemove', handleMouseMove);
}, []);

return position;
}

function App() {
const { x, y } = useMousePosition();

return (
<div>
Mouse position: {x}, {y}
</div>
);
}






Advantages over HOCs and Render Props:




  • Simpler syntax

  • No wrapper components

  • Easy to compose multiple hooks

  • Clear dependencies



This is why React recommends hooks over HOCs and render props.









Part 4: Composing Hooks



Custom hooks can be composed just like components:




function useAuth() {
const [user, setUser] = useState(null);

useEffect(() => {
// Fetch user from API
const fetchUser = async () => {
const userData = await api.getUser();
setUser(userData);
};
fetchUser();
}, []);

return { user, isAuthenticated: !!user };
}

function usePermissions(user) {
const [permissions, setPermissions] = useState([]);

useEffect(() => {
if (user) {
const fetchPermissions = async () => {
const perms = await api.getPermissions(user.id);
setPermissions(perms);
};
fetchPermissions();
}
}, [user]);

return permissions;
}

function useDashboard() {
const { user, isAuthenticated } = useAuth(); // Compose hooks!
const permissions = usePermissions(user);

return { user, isAuthenticated, permissions };
}

function Dashboard() {
const { user, isAuthenticated, permissions } = useDashboard();

if (!isAuthenticated) {
return <div>Please log in</div>;
}

return (
<div>
<h1>Welcome, {user.name}!</h1>
<p>Permissions: {permissions.join(', ')}</p>
</div>
);
}






Key Point: Hooks compose horizontally (call multiple hooks), while inheritance composes vertically (extend classes).









Part 5: When Inheritance Might Make Sense (Rarely)



There are a few cases where inheritance is acceptable in JavaScript/React:






1. Extending Built-in Classes






class MyArray extends Array {
first() {
return this[0];
}

last() {
return this[this.length - 1];
}
}

const arr = new MyArray(1, 2, 3);
console.log(arr.first()); // 1
console.log(arr.last()); // 3






Use case: Adding utility methods to built-in types.









2. Third-Party Library Requirements



Some libraries require extending their classes:




import { Component } from 'some-library';

class MyComponent extends Component {
// Library requires extending Component
}






But: In React, you rarely need to extend React.Component anymore — use functional components instead.









Part 6: Composition Anti-Patterns






Anti-Pattern 1: Prop Drilling



Passing props through many levels:




function App() {
const user = { name: 'Alice' };
return <Layout user={user} />;
}

function Layout({ user }) {
return <Sidebar user={user} />;
}

function Sidebar({ user }) {
return <UserMenu user={user} />;
}

function UserMenu({ user }) {
return <div>{user.name}</div>;
}






Problem: Every component needs to pass user down, even if it doesn't use it.



Solution: Use Context API or state management:




const UserContext = React.createContext();

function App() {
const user = { name: 'Alice' };
return (
<UserContext.Provider value={user}>
<Layout />
</UserContext.Provider>
);
}

function UserMenu() {
const user = useContext(UserContext); // No prop drilling!
return <div>{user.name}</div>;
}












Anti-Pattern 2: Over-Abstraction



Creating too many generic components:




function GenericContainer({ type, className, style, children, ...props }) {
const Component = type || 'div';
return (
<Component className={className} style={style} {...props}>
{children}
</Component>
);
}

// Usage becomes confusing
<GenericContainer type="section" className="container" style={{ padding: 10 }}>
Content
</GenericContainer>






Problem: Too generic — harder to understand than just using <section>.



Solution: Create specific, purposeful components:




function Section({ children }) {
return <section className="container">{children}</section>;
}












Quick Reference Cheat Sheet











































Pattern Use Case Example

children prop
Containment, generic wrappers <Card>{content}</Card>
Named props Multiple composition points <Dialog title={...} content={...} />
Specialization Specific versions of generic components
<PrimaryButton> from <Button>
HOCs Adding behavior to multiple components withLoading(Component)
Render Props Sharing stateful logic <Tracker render={data => ...} />
Custom Hooks Modern logic composition
useAuth(), useMousePosition()








Key Takeaways



Composition is more flexible than inheritance — you can mix and match behaviors

React prefers composition — use children props, HOCs, render props, and hooks

Inheritance creates tight coupling — hard to change and reuse

Custom hooks are the modern way to compose logic — simpler than HOCs and render props

Use the children prop for containment — makes components maximally reusable

Avoid deep component hierarchies — prefer flat composition

Context API solves prop drilling — no need to pass props through every level









Interview Tip



When asked about composition vs inheritance:




  1. "Composition means building complex components by combining simpler ones, while inheritance means creating hierarchies of classes"

  2. Explain the problem: "Inheritance creates rigid hierarchies that are hard to change. If you need to mix behaviors from multiple base classes, you're stuck."

  3. React's approach: "React uses composition patterns like children props, HOCs, render props, and now custom hooks to share logic"

  4. Best practice: "Use custom hooks to compose logic and the children prop to compose UI"

  5. Example: "Instead of extending a BaseButton class, create a Button component that accepts props, then create PrimaryButton that renders Button with specific props"



Now go forth and compose fearlessly!

Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Composition vs Inheritance: Why React Chose the "Has-A" Over "Is-A" Relationship

Thematisch verwandte Begriffe: Composition, Inheritance, React, Chose · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-5695 | Arbitrary file upload vulnerability due to a lack of proper validation in…
Advisory →
TTS Reader • tsecurity.de Voice
tsecurity.de Icon
tsecurity.de App
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag
Themen-Radar & Intelligence Matrix
Echtzeit-Taxonomie nach Angriffsvektoren & Plattformen

tsecurity.de Live Threat Radar

🔴 LIVE RADAR
MONITORING
AKTIV
CVE-DATENBANK
LIVE
🔍
Community Radar & Live Chat
Sentinel Bot online • Live-Stream
Dein Cluster: Security Explorer
Match:
lädt…
Verbindung zum Community-Stream wird aufgebaut...
Bearbeitungsmodus — Senden überschreibt deine Nachricht
Community-Puls — was gerade passiert
lädt…
Aktivitäten deiner Analysten
lädt…
Neues Thema oder Eilmeldung einreichen

Reiche interessante Links, Zero-Days oder Debatten ein. Die Community entscheidet per Upvote über die Veröffentlichung.

Heiß diskutierte Einreichungen
🔖 Gespeicherte Artikel
📂 Keine gespeicherten Artikel vorhanden.
Zurück Ziehen Vor
Links: vorheriger Artikel Rechts: nächster Artikel unten: schließen
News NIS-2 Frühwarnung Tier-1 Intel ⏱️ 3 Min vor 10 Min
Artikeldaten werden geladen...

Zurück: vorheriger Vor: nächster
↗ Original-Quelle
Social Reaktionen Deine Reaktion zählt
Einstufung & Relevanz-Poll 0 Stimmen
In sozialen Netzwerken teilen 1-Klick