모던 웹 개발에서 컴포넌트 기반 아키텍처는 빠르게 표준이 되었습니다. 특히 React와 같은 라이브러리를 사용하면 UI를 작은, 재사용 가능한 컴포넌트로 분리하여 개발하는 것이 일반적입니다. 하지만 이 과정에서 단순히 컴포넌트를 나누는 것만으로는 부족합니다. 여기서 중요한 개념이 바로 컴포넌트 합성입니다.
컴포넌트 합성은 여러 개의 작은 컴포넌트를 조합하여 더 큰 기능을 수행하는 컴포넌트를 만드는 방법을 의미합니다. 이 접근 방식은 코드의 재사용성을 높이고, 유지보수를 쉽게 하며, 복잡한 UI를 관리하는 데 매우 유용합니다. 따라서 컴포넌트 합성은 단순히 좋은 습관이 아니라, 효율적이고 확장 가능한 애플리케이션을 개발하는 데 필수적인 기술입니다.
이번 글에서는 컴포넌트 합성이 왜 중요한지, 어떻게 적용할 수 있는지, 그리고 이를 통해 얻을 수 있는 다양한 이점에 대해 살펴보겠습니다.
컴포넌트 합성?
쉽게 말하자면, "컴포넌트에서 다른 컴포넌트를 담기" 라고 보시면 됩니다.
const Parent = ({ children }) => (
<div>{children}</div>
)
const App = () => {
<Parent>
<Child/>
</Parent>
}
위의 코드처럼 부모 컴포넌트에서는 children이라는 특수 props를 사용해서 자식 컴포넌트를 렌더링할 수 있습니다. 하지만, 꼭 children을 사용할 필요는 없고 아래와 같이도 사용이 가능합니다.
아래 코드와 같이 props를 통해서 컴포넌트를 주입하는 방식도 컴포넌트 합성이라고 말할 수 있습니다.
const SplitPane = (props) => (
<section>
<div>
{props.left}
</div>
<div>
{props.right}
</div>
</section>
)
const App = () => (
<SplitPane
left={
<Contacts />
}
right={
<SideMenu />
}
/>
)
합성의 장점
1. 재사용성
React에서는 다음과 같이 말합니다.
“합성을 사용하여 컴포넌트 간에 코드를 재사용하는 것이 좋습니다.”
그렇다면 어떻게 재사용이 될까요?
만약 잘 만들어 놓은 버튼이 있다면, 사용부에서 컴포넌트를 주입함으로써 만들어놓은 컴포넌트를 재사용할 수 있습니다.
const Button = () => (
<button>버튼</button>
)
const UI = () => (
<Layout>
<Button />
</Layout>
)
2. SRP
SRP(Single Responsibility Principle)는 쉽게 말하면 관심사의 분리입니다.
컴포넌트 합성을 이용하면 SRP를 더욱 명확하게 달성할 수 있습니다.
아래 코드를 보시면 한 컴포넌트 내에서 데이터 패칭, 에러 핸들링 그리고 로딩에 대한 처리가 모두 한 번에 일어나고 있는 것을 확인할 수 있습니다.
const LegenedComponent = () => {
const { data, isLoading, isError } = useFetch();
if (isError) return <div>error...!</div>;
if (isLoading) return <div>loading...!</div>;
return <div>{data}</div>;
}
위의 코드가 안좋은 코드는 아니지만, 합성을 통해서 좀 더 개선을 하자면 좀 더 익숙한 형태인 아래와 같은 코드가 작성됩니다. 에러 바운더리와 서스펜스를 사용하였고, 대표적으로 합성을 통해서 관심사를 분리한 예시입니다.
const UI = () => (
<ErrorBoundary fallback={<div>error...!</div>}>
<Suspense fallback={<div>loading...!</div>}>
<LegenedComponent />
</Suspense>
</ErrorBoundary>
)
위의 코드처럼 작성하면 에러에 대한 로직과 로딩에 대한 로직이 변경되어도 새롭게 추가한 LegenedComponent에는 아무런 영향이 일어나지 않습니다. 서로가 서로에 대해서 아무것도 알고 있지 않기 때문입니다.
References
https://ko.legacy.reactjs.org/docs/composition-vs-inheritance.html
'1. 웹개발 > 1_1_5 React JS' 카테고리의 다른 글
[React] Compound Pattern 파헤치기 (0) | 2024.07.13 |
---|---|
[React] Flux 패턴과 Elm 아키텍처 (0) | 2024.05.18 |
[React] 성능을 측정하는 지표 (LCP, FID, CLS, FCP, TTFB 등) (0) | 2024.05.11 |
[React] forwardRef와 useImperativeHandle 훅이란? (0) | 2024.05.01 |
[React] 커스텀훅 vs 고차 컴포넌트 (0) | 2024.04.27 |