728x90
728x90
Compound Component 패턴
들어가며
- 리액트(React.js)에서 자주 사용되는 디자인 패턴(Design Pattern) 중 하나인 Compound Component 패턴에 대해 정리해본다.
Compound Component 패턴
개념
- 서로 관련된 여러 개의 컴포넌트를 하나의 부모 컴포넌트 안에 캡슐화하는 방식
- 컴파운드 컴포넌트의 주요 아이디어는 사용자 인터페이스(UI)를 구성하는 여러 작은 컴포넌트를 하나의 상위 컴포넌트 안에서 조합하여 더 복잡한 UI를 만드는 것이다.
Coompound Component 패턴의 적용 예 : @<select> - <option>@
<select>
<option>Option 1</option>
<option>Option 2</option>
<option>Option 3</option>
<option>Option 4</option>
</select>
장점
- 동일한 컴포넌트를 다양한 방식으로 재사용할 수 있다.
- 컴포넌트의 내부 구조를 변경하지 않고도 다양한 UI 구성을 만들 수 있다.
- 복잡한 UI를 작은 컴포넌트로 나누어 구성함으로써 코드가 더 이해하기 쉽게 된다.
예제 코드
import React, { useState, createContext, useContext } from 'react';
const AccordionContext = createContext();
const Accordion = ({ children }) => {
const [openIndex, setOpenIndex] = useState(null);
const toggleIndex = (index) => {
setOpenIndex((prevIndex) => (prevIndex === index ? null : index));
};
return (
<AccordionContext.Provider value={{ openIndex, toggleIndex }}>
<div className="accordion">{children}</div>
</AccordionContext.Provider>
);
};
const AccordionItem = ({ children, index }) => {
const { openIndex, toggleIndex } = useContext(AccordionContext);
const isOpen = openIndex === index;
return (
<div className={`accordion-item ${isOpen ? 'open' : ''}`}>
{React.Children.map(children, (child) =>
React.cloneElement(child, { isOpen, index, toggleIndex })
)}
</div>
);
};
const AccordionHeader = ({ children, index, toggleIndex }) => (
<div className="accordion-header" onClick={() => toggleIndex(index)}>
{children}
</div>
);
const AccordionBody = ({ children, isOpen }) => (
isOpen ? <div className="accordion-body">{children}</div> : null
);
const App = () => (
<Accordion>
<AccordionItem index={0}>
<AccordionHeader>Header 1</AccordionHeader>
<AccordionBody>Body 1 Content</AccordionBody>
</AccordionItem>
<AccordionItem index={1}>
<AccordionHeader>Header 2</AccordionHeader>
<AccordionBody>Body 2 Content</AccordionBody>
</AccordionItem>
<AccordionItem index={2}>
<AccordionHeader>Header 3</AccordionHeader>
<AccordionBody>Body 3 Content</AccordionBody>
</AccordionItem>
</Accordion>
);
export default App;
참고 사이트
728x90
728x90
'Programming > React' 카테고리의 다른 글
[React.js] 리액트 스니펫(Snippet) 정리 (0) | 2024.08.26 |
---|---|
[React.js] Create React App과 Vite (0) | 2024.08.26 |
[React.js] 함수형 업데이트와 직접 참조 업데이트 (0) | 2024.08.22 |
[React.js] 조건부 렌더링 방법 정리 (0) | 2024.08.22 |
[React.js] Framer Motion 라이브러리 (0) | 2024.08.11 |
[React.js] Suspense 컴포넌트 (0) | 2024.08.06 |
[React.js] 낙관적 업데이트(Optimistic Updates) (React Query) (0) | 2024.07.10 |
[React.js] 리액트 쿼리(Tanstack Query, React Query) (0) | 2024.07.09 |