UI 구현을 하다 보면 컴포넌트에 여백(margin)을 어떻게 적용해야 할지 고민이 될 때가 많았다. 특히 재사용 할 컴포넌트라면 사용하는 위치에 따라 여백이 달라져 수정을 하게되는 경험이 많아서 CSS를 작성할 때마다 고민이 되는 부분이었다.
예를 들어 A 페이지에서는 20px의 여백이 필요하지만, B 페이지에서는 10px 필요한 경우이다.
처음에는 컴포넌트에 직접적으로 여백을 적용한 뒤, 다른 페이지에서 재사용할 경우 해당 페이지의 다른 컴포넌트로 여백을 옮기곤 했다.
이 방식의 문제는 여백을 옮긴 컴포넌트 1, 컴포넌트 4도 어딘가에서 재사용될 경우 발생한다.
컴포넌트 1이 재사용 된다면 여백을 또 어디로 옮겨야 할까?
정말 정말 처음에는 컴포넌트 내부에 css로 여백을 선언하다 이런 상황을 몇 번 겪고는 컴포넌트를 호출할 때 여백을 props로 넘겨주기로 했다.
타입스크립트에서 컴포넌트를 선언할 때 HTMLElement
의 type들을 상속받으면 className을 직접 선언하지 않아도 props로 넘겨줄 수 있기 때문에 이 방법이 유효했다. 그런데 모든 컴포넌트가 HTMLElement
타입을 상속받지 않을 수 있다. 그런 경우에는 또 어디에 여백을 주냐 하는 고민이 생겼다.
이런 케이스가 생기다 보니 컴포넌트 자체에 여백을 직접 주지 않는 방법을 생각해 봤다. A 페이지 B 페이지마다 여백이 다르다는 건 그 여백들은 해당 페이지 내부에서만 필요한 정보(?)라고 생각했다.
그러다 Container, Presentation 패턴을 보고 Presentation 컴포넌트를 만들어 배치, 여백 관련 스타일을 적용하면 되겠다는 생각이 들었다.
const SomePage = () => (
<div className="max-w-[980px] mx-auto mt-6 mb-16">
<div className="px-4">
<div className="mb-4">
<TypographyH4>제목</TypographyH4>
</div>
</div>
<div className="mt-4">
<MyComponent/>
</div>
</div>
);
이렇게 레이아웃 관련 스타일을 적용하는 컴포넌트를 만들어서 사용했다. 그러니 또 다른 페이지를 구현해도 그 페이지를 위한 Presentation 컴포넌트를 만들어 사용하면 되고 기존 재사용 컴포넌트는 수정할 필요가 없어져 유지 보수가 쉬워졌다.😎
유지 보수가 유리해진 건 좋은데 단순 스타일을 위한 태그가 너무 많아지는 것 아닌가 하는 고민이 되긴 한다. 또한 Container, Presentation 패턴을 사용하면 파일이 많아지고 코드 베이스가 복잡해질 수도 있다고 하는데 이 부분은 프로젝트가 커질 경우라 현재 우리 프로젝트에서는 문제보단 유지 보수가 용이해진 장점이 더 크다.
결론적으로, 현재 프로젝트에서는 컴포넌트의 여백 같은 레이아웃 관련 부분을 부모 요소, Presentation 컴포넌트에 위임하는 방식으로 코드를 작성하려 한다. 추가적으로 패턴에 대한 공부를 더 해볼 필요성이 느껴진 고민이었다.