Component Composition là kỹ thuật xây dựng các component phức tạp bằng cách "lắp ráp" hoặc "chứa" các component đơn giản hơn (giống như Lego), thay vì dùng cơ chế kế thừa (inheritance) của Lập trình Hướng đối tượng (OOP).
Tại sao React khuyến khích Composition?
- Tránh sự phức tạp của cây kế thừa (Prototype Chain): Kế thừa nhiều tầng dễ dẫn đến code rối rắm (spaghetti code), khó bảo trì và dễ bị ảnh hưởng dây chuyền (fragile base class).
- Linh hoạt và tái sử dụng cao: Bạn có thể dễ dàng thay đổi cấu trúc UI bằng cách thay đổi component con truyền vào mà không cần sửa code của component cha.
- Đúng với bản chất của UI: UI thường là sự bao bọc (một Dialog chứa nội dung bên trong) thay vì quan hệ "là một" (is-a) như OOP.
Các pattern phổ biến của Composition:
1. Containment (Bao bọc): Dùng prop đặc biệt children để truyền tuỳ ý các node con vào bên trong wrapper.
function Card({ children }) {
return <div className="card-box">{children}</div>;
}
// Sử dụng:
<Card> <h1>Tiêu đề</h1> <p>Nội dung...</p> </Card>2. Specialization (Đặc biệt hóa): Tạo ra một component cụ thể bằng cách truyền cấu hình (props) cố định vào một component chung hơn.
function PrimaryButton(props) {
return <Button {...props} color="blue" />;
}Component Composition is the technique of building complex components by assembling or nesting simpler components (like Lego blocks), rather than using Object-Oriented inheritance.
Why React favors Composition:
- Avoids rigid inheritance hierarchies: Deep inheritance trees lead to complex, tightly-coupled, and fragile code.
- Flexibility and Reusability: You can easily alter UI structures by swapping out child components without modifying the parent component's code.
- Aligns with UI nature: UIs are naturally composed of nested boxes (a Dialog containing arbitrary content) rather than strict "is-a" OOP relationships.
Common Composition Patterns:
1. Containment: Using the special children prop to pass arbitrary nested nodes into a wrapper.
function Card({ children }) {
return <div className="card-box">{children}</div>;
}
// Usage:
<Card> <h1>Title</h1> <p>Content...</p> </Card>2. Specialization: Creating a specific component by passing predefined props to a more generic component.
function PrimaryButton(props) {
return <Button {...props} color="blue" />;
}