
프로젝트를 진행하면서, 위 UI 기능을 구현하기 위해 아래와 같은 컴포넌트를 개발했습니다.

도메인 로직과 UI 로직이 강하게 결합되어 있는 컴포넌트는 재사용하기 어렵기 때문입니다.
지금까지 ButtonsInput 컴포넌트는 사용자로부터 서버로 전송할 양식을 받기 위해 폼에서 사용되고 있었습니다.
만약 form 외부에서 사용된다고 했다면 어땠을까요? 컴포넌트를 구현하기 이전에 form이라는 도메인과의 의존성을 분리했을 것 같습니다.
Bottom-Up 방식 개발론이 Top-Down 방식의 개발보다 의존성을 분리하기 쉬운 이유가 이와 같습니다.
만일 아래와 같은 요구사항이 추가 되었다고 가정하겠습니다.
💬 옵션이 선택되었을 때 해당 옵션을 설명하는 모달을 사용자에게 띄워주세요.
💬 A 페이지에 필터링 기능이 필요해서 구현해주시는데, 원래 사용되던 UI 그대로 사용하시고 이러한 옵션들로 필터링 기능을 추가해 주세요.
같은 UI이지만 form 내부가 아닌 다른 경우에 사용해하는 경우가 왔습니다. 기존 컴포넌트를 어떻게 하면 될 것 같은데.. 잘 감이 오지 않습니다.
기존의 컴포넌트를 수정하기보다는 새로 하나 만드는게 나을 것 같습니다. 이런 실수를 반복하지 않기 위해 컴포넌트를 어떤 기준으로 구현하는 것이 좋을지 알아보겠습니다.
변경에 유연하게 대처할 수 있도록 컴포넌트를 “잘” 만들어야 합니다.
그러기 위해서 세 가지 요소를 고려할 수 있습니다.
예시로 들었던 컴포넌트가 동작하기 위한 기본적인 동작을 고민해보겠습니다.

수행하는 기본적인 컴포넌트의 동작은 여러 개의 옵션이 존재하며 선택할 수 있다 입니다.
여러 개의 옵션이 존재하며 선택할 수 있다는 책임 "하나"만을 가지는 컴포넌트로 다시 구현하면 어떤것이 개선될 수 있는지 보겠습니다.
수정을 거쳐서 아래와 같은 인터페이스로 개선되었습니다.


이제 아까의 요구사항을 반영해 보겠습니다.
💬 옵션이 선택되었을 때 해당 옵션을 설명하는 모달을 사용자에게 띄워주세요.
💬 A 페이지에 필터링 기능이 필요해서 구현해 주시는데, 원래 사용되던 UI 그대로 사용하시고 이러한 옵션들로 필터링 기능을 추가해 주세요.
기존에는 감조차 오지 않았지만, 이제는 컴포넌트의 이벤트 리스너를 활용해 해당 요구사항을 반영할 수 있습니다.
어떠한 기능을 구현할 때는 표면상에 드러난 기능만을 바라보기보다 일반적인 부분과 그렇지 않은 부분을 구분하고, 기능을 구현해야 합니다.
사람은 무언가를 파악할 때 기존에 알고 있던 내용을 바탕으로 파악하기에 컴포넌트 인터페이스는 일반적일수록 이해가 쉽습니다.
사람마다 알고 있는 것이 다르기 때문에 최대한 많은 사람이 알만한 인터페이스로 표현하는 것도 중요합니다.
Context API를 활용해 암시적으로 상태를 공유하도록 하는 컴파운드 컴포넌트 패턴을 활용해 더 일반적인 인터페이스로 개선해 보겠습니다.


일반적인 인터페이스로 컴포넌트를 개선하면서 컴포넌트 다운 컴포넌트로 개선할 수 있었습니다.
UI 로직과 도메인 로직을 분리함으로 외부 라이브러리와의 의존을 끊어냈습니다. 드러내야 할 부분은 잘 드러내고 있고, 컴포넌트의 역할이 명확해지고 재사용성도 올라갔습니다.

