HomeAboutMeBlogGuest
© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
🤎
프론트엔드 데브코스 5기 교육생
/
소인성팀
소인성팀
/
팀프로젝트-모모
팀프로젝트-모모
/
💻
공부
/
합성 컴포넌트 패턴

합성 컴포넌트 패턴

태그
날짜
Jan 6, 2024
사람
문제점
Input 공용 컴포넌트를 맡게 되었는데 처음에는 간단한 로직이었지만 추가 요구사항이 많아지면서 모든 상황에 다 맞춰야 하면서 동시에, 많은 props를 받아야하는 문제점이 생기고, 얼마나 더 많은 요구사항이 생길지 모르게 되었다.
 
해결
멘토님께 문제를 말씀 드렸더니 많은 해결법을 주셨는데, 그 중 합성 컴포넌트를 찾아보게 되었다.
 
합성 컴포넌트 패턴이란?
하나의 컴포넌트를 여러 가지 관심사로 분리하고 분리된 관심사는 사용되는 곳에서는 원하는 관심사만 조합을 하며 사용하는 패턴이다.
 
쉽게 말해서 html의 select를 생각하면 좋을 것 같다.
<select> <option value="1">Option 1</option> <option value="2">Option 2</option> <option value="3">Option 2</option> </select>
select 태그는 option에 대한 것들을 담고 있고, option은 각각의 value에 대한 것들을 담고 있다.
또한 value2를 사용하고 싶을 때는 value1, value3을 제외한 value2만 사용하면 된다.
 
notion image
notion image
 
실제 사용에서도 동일하게
select - InputContainer
option - Image, Tags, Text, TextArea
위와 같은 방식으로 넣었어서 작업을 진행하였다.
 
참고
InputContainer - 입력 요소들을 감싸는 컴포넌트 역할
InputImage - 이미지 입력을 다루는 파일
InputTags - 태그 입력을 다루는 파일
InputText - 텍스트 입력 다루는 파일
InputTextArea - 다중 행 텍스트 입력 다루는 파일
 
사용 방법
  1. InputText만 사용하고 싶을때
<InputCompound style={{ width: '300px' }}> <InputCompound.Text placeholder="이메일" value={email} onChange={(e) => setEmail(e.target.value)} ref={emailRef} onKeyUp={handleOnKeyUp} /> </InputCompound>
  1. InputText와 Tags를 동시에 사용하고 싶을때
<InputCompound style={{ width: '350px' }}> <InputCompound.Text placeholder="태그" }} /> <InputCompound.Tags tags={tags} setTags={(arg) => setTags(arg)} /> </InputCompound>
 
 
장점
  1. 많은 props를 컨트롤 할 수 있다.
- 단순 Input 컴포넌트를 만들때는 props를 일일이 제어해야하고 복잡했는데, 합성 컴포넌트를 활용하면서 관심사별로 props를 각각 넣을 수 있는 장점이 있었다.
  1. 계층 구조가 한눈에 드러나서 직관적으로 확인 할 수 있다.
  1. UI 변경에 강하다.
  1. props drilling에 대한 대처가 이전보다 더 완화할 수 있다.
 
단점
  1. 간단한 input인데도 코드가 더 길어질 때가 있어서 가독성이 떨어질때가 있다.
 
추가
  1. 데이터 컨트롤은 안이 아닌 밖에서 핸들링을 하게 하여 여러 페이지에서 사용할 수 있도록 하였다.
  1. input 컴포넌트의 여러 옵션에 대해서 InputHTMLAttributes<HTMLInputElement>를 오버라이드 해서 사용하여 축약할 수 있었다.