이번에 새로운 결제 페이지 작업을 하게 되었다. 기존 UI와 거의 동일하지만 내부 로직이 약간씩 달라지면서 기존에 있던 컴포넌트를 재사용할지, 새로 만들어야 할 지 고민이 되었다. 새로 만들면 기존 컴포넌트의 설계와 다른 컴포넌트 또는 hook과의 상호작용에 대해 전혀 고려하지 않아도 되기 때문에 가장 간단하고 쉬운 방법이었지만 그렇게 계속 만들게 될 경우 중복 코드가 너무 많아질 것이라는 생각이 들었다. 그래서 기존 컴포넌트를 가져다 쓰되 기존 로직과 결부되어 있는 부분을 props로 받도록 해서 컴포넌트 내부에서 도메인 로직을 갖지 않도록 분리하는 작업이 필요했다.
기존 컴포넌트는 특정 store에서 필요한 변수들을 받아와 조작해 view에 렌더링 하는 방식이었는데 store에서 받아오는 변수를 props로 받도록 수정하고 필요한 값을 주입받는 방식으로 변경했다.
당장 할 수 있는 최선의 방법이었으나, props로 받다보니 props drilling이 발생하지 않게 하기 위해서 전역 스토어를 사용한 것인데 또 props를 받는 게 어쩐지 별로였다. 그래서 특정 flag 값을 두어 flag별 스토어(or hook)를 가져와서 필요한 변수를 export는 하는 hook을 만들까도 생각해보았지만 이것 역시 이마를 탁 치게 만드는 방법은 아니었다.
전역 스토어를 생성하고 필요한 컴포넌트에서 가져다 쓰는 방식이 좋다고 생각했는데 도메인 로직과 무관하지 않다는 점에서 단순히 로직을 다른 파일에 둔 것일 뿐, 재사용성에는 큰 도움이 되지 않았다.
상태가 없는 UI 컴포넌트와 로직을 가진 컴포넌트를 제대로 분리하는 기준을 갖지 못한 것이 문제였다. 개발 당시에는 확장가능성을 전혀 고려하지 않다가 누더기처럼 is~ 같은 플래그 값을 props로 받아 계속 분기문을 치는 누더기 컴포넌트를 만드는 게 문제였던 것 같다.
지속 가능하게 그리고 더 쉽게 프론트엔드 개발을 하기 위해서는 상태를 가질 컴포넌트와 layout만을 담당할 컴포넌트를 분리해야 하고 가장 작은 단위의 atomic 컴포넌트는 자기 자신이 상태를 갖고 있기 보다는 상태와 핸들러를 주입받는 형태로 구성되어야 다른 컴포넌트에서 재사용이 훨씬 쉬워질 것이다.
또 UI를 그리는 부분이라도 해당 컴포넌트에서 필수 요소인지 아니면 옵셔널한 부분인지도 구분해야 한다. 옵셔널한 부분이라면 slot(children)으로 부모에게 주입받는 형태로 사용하는 것이 layout 구성 측면에서 더 나을 수도 있다.
이제 집에 가서 위의 기준에 따라 리팩토링을 해야겠다.
fin.