React Compound Component

react에서 compound component 패턴을 사용하면 props drilling 없이 선언적이고 표현적인 컴포넌트를 만들 수 있게 됩니다.
compound 패턴은 하나의 컴포넌트를 구성하는 암시적 상태 공유 컴포넌트 API 집함을 제공하는 방법으로 매우 유연하며 확장성이 뛰어납니다.
이번 포스트에서는 아주 간단한 예제를 통해 compound component 패턴에 대해서 설명해보고자 합니다.
한 가지 예로 다음과 같은 구조를 가지고 있는 Card 컴포넌트가 있다고 하겠습니다.
특별한 점이 없어 보입니다ㅎ
다음은 Card 컴포넌트 내부에 heading을 추가하기 위한 Heading 컴포넌트를 정의해보겠습니다
이제 Card 컴포넌트 내부에 Heading 컴포넌트를 추가하면 다음과 같이 적용하게 됩니다.
기본적으로 많이 사용되는 방식이라고 생각됩니다만 Heading 컴포넌트는 다음과 같이 Card 컴포넌트 외부에서도 사용 할 수 있어 Card 내부에 속하는 요소로 보이지는 않습니다.
그렇다면 조금 방식을 바꿔보겠습니다.
Heading 컴포넌트를 Card 컴포넌트 property로 추가하였습니다. 이게 가능한 이유는 react에서 모든 컴포넌트는 객체로 virtualDOM으로 추가되기 때문입니다.
이제 Heading 컴포넌트를 사용하는 방식은 다음과 같이 바뀌게 됩니다. 이전과 다르게 Heading 컴포넌트는 Card 컴포넌트에 속하는 요소로 보여집니다.
하지만 여전히 Card 컴포넌트 외부에서 사용 될 수 있다는 문제점은 해결되지 않았습니다.
Context 활용을 통한 범위 제한
컴포넌트가 내부에서만 사용 가능할 수 있도록 범위 제한을 하고 싶다면 context api를 활용하면 됩니다.
먼저 위에 작성했던 Card 컴포넌트를 다음과 같이 context를 생성해준 뒤 Provider로 감싸주도록 수정해줍니다.
다음으로 Heading 컴포넌트 내부에서 useContext를 통해 context 값에 접근 할 수 있도록 하고 context가 존재하는 경우(Card 컴포넌트 내부에서 위치한 경우) 정상 랜더링 되도록 수정해줍니다.
이제 <Card.Heading> 을 Card 컴포넌트 외부에서 랜더링을 진행한 다면 card 컴포넌트 내부에 위치해야됩니다!! 라는 문구가 화면에 나타나게 되어 내부에서만 사용 할 수 있게 됩니다.
custom hook으로 분리하기
매번 context 접근을 하며 에러 체크 로직을 각 컴포넌트 내부에 반복적으로 작성하는 것은 매우 귀찮은 일입니다… 반복되는 코드를 한 곳에서 관리하도록 custom hook을 활용해보겠습니다.
context가 존재하지 않을 경우 에러를 발생 시키도록 useCardContext 훅을 작성하였습니다.
컴포넌트를 추가 할 때마다 이 훅을 사용하여 Card 컴포넌트 내부에서 만 사용 될 수 있도록 제한 및 context에 접근 할 수 있도록 할 수 있으며 이를 통해 상태관리 역시 진행 할 수 있습니다.
결과물 샘플

참고

© 2024 dan.dev.log, All right reserved.

Built with NextJS