-> Compound component 패턴에 대해 설명하기 전, 프론트엔드에서 디자인 패턴이 필요한 이유를 먼저 설명하고자 한다.
시간이 지날수록 웹 어플리케이션은 점점 복잡해지고 고도화되고 있다. 또한 UX 개선, 다양한 디바이스 대응등 프론트엔드가 해결해야할 과제들은 늘어나고 있다. 웹 어플리케이션의 복잡성이 늘어나고 있는데, 이를 해결하지 못한다면, 유지보수가 힘들고 성능이 저하될 가능성이 높다. 이를 해결하는 방법 중 한개가 디자인 패턴이다.
→ 혼자 동작하지 않고 연결된 합성 컴포넌트
ex) select 태그와 option 태그는 같이 사용되게 구성되어 있다(리액트를 벗어난 관점)
“ 합성을 사용하여 컴포넌트 간에 코드를 재사용 하는 것이 좋다 ”
SRP(단일 책임 원칙)
Props drilling 문제를 해결 할 수 있다.
선언적이고 이해하기 쉬운 컴포넌트를 작성할 수 있다.
UI 구조를 유연하게 변경할 수 있다.
ex) Accordion


import { Accordion } from './components/Accordion/Accordion';
function App() {
return (
<main>
<section>
<h2>Why work with us?</h2>
<Accordion className="accordion">
<Accordion.Item id="experience" className="accordion-item">
<Accordion.Title className="accordion-item-title">
we got 20 years of experience
</Accordion.Title>
<Accordion.Content className="accordion-item-content">
<article>
<p>You cant go wrong with us.</p>
<p>We are hiring</p>
</article>
</Accordion.Content>
</Accordion.Item>
<Accordion.Item id="local-guides" className="accordion-item">
<Accordion.Title className="accordion-item-title">
we're working with local guides
</Accordion.Title>
<Accordion.Content className="accordion-item-content">
<article>
<p>You cant go wrong with us.</p>
<p>We are hiring</p>
</article>
</Accordion.Content>
</Accordion.Item>
</Accordion>
</section>
</main>
);
}
export default App;
import { createContext, useState, useContext } from 'react';
import AccordionItem from './AccordionItem';
import AccordionContent from './AccordionContent';
import AccordionTitle from './AccordionTitle';
const AccordionContext = createContext();
export function useAccordionContext() {
const ctx = useContext(AccordionContext);
if (!ctx) {
throw new Error('Error!');
}
return ctx;
}
export function Accordion({ children, className }) {
const [openItemId, setOpenItemId] = useState();
function toggleItem(id) {
setOpenItemId((prev) => (prev === id ? null : id));
}
const contextValue = {
openItemId,
toggleItem,
};
return (
<AccordionContext.Provider value={contextValue}>
<ul className={className}>{children}</ul>
</AccordionContext.Provider>
);
}
Accordion.Item = AccordionItem;
Accordion.Title = AccordionTitle;
Accordion.Content = AccordionContent;
Accordion.Item = AccordionItem;
Accordion.Title = AccordionTitle;
Accordion.Content = AccordionContent;