컴포넌트의 역할과 책임

박성훈·2025년 1월 3일

dev_log

목록 보기
4/6
post-thumbnail

이 글은 회사 재직기간 동안 다양한 컴포넌트를 설계 및 유지보수하면서 느낀 점을 기록하기 위해 작성하였습니다.

📌 컴포넌트

컴포넌트의 정의를 한번 말해본다면
"재사용 가능한 독립적인 모듈" 이라고 할 수 있을 것 같습니다.
그래서 컴포넌트 기반의 웹개발을 할 때, 우리는 이 컴포넌트를 만들고 조합해서 하나의 웹 페이지를 만들게 되죠.

컴포넌트를 조합한다라는 것은 단순히 1개의 컴포넌트가 아닌 여러 개의 컴포넌트가 존재하는 뜻이고, 어떠한 기준으로 코드가 분리되어 모듈화되었다는 의미로 생각할 수 있습니다.

📌 컴포넌트의 역할을 생각하지 않았을 때

저는 처음 컴포넌트를 분리시키는 기준, 그리고 목적을 코드의 가독성 증대와 재사용성 향상으로 인한 개발 속도 단축으로 생각했습니다.
그렇기 때문에, 개발을 하면서 코드가 복잡해지거나, 재사용할 수 있을 것 같은 코드 덩어리가 나오면 컴포넌트로 만들어야겠다는 생각을 했죠.

그러다 보니, 다음과 같은 절차로 개발을 했습니다.

  1. 일단 페이지 컴포넌트를 만든다.
  2. 그 컴포넌트에서 쭉 기능개발을 한다.
  3. 어? 이거는 나중에 재사용할 수도 있겠네? 컴포넌트로 따로 만들어야 겠다.
  4. 여기서 이 로직까지 있으면 너무 코드 가독성이 떨어지니까 관심사를 분리시켜야겠다.
  5. 컴포넌트 안에 코드를 분리시키니까 짧아지고 좋네!

저는 이런 방식이 숲이 아닌 나무만 바라보는 좋지 않은 습관이고, 코드에 매몰되는 지름길이라는 점을 회사에서 다양한 컴포넌트를 만들어보면서 느낄 수 있었습니다.

일단, 이렇게 했을 때의 문제점은 다음과 같습니다.

  1. 명확한 목적을 가지고 컴포넌트를 만드는 것이 아니다보니 다른 컴포넌트에 이미 들어있는 코드를 다시 작성하게 되는 경우가 발생한다.
  2. 구조를 먼저 생각하지 않고 개발을 진행하다보니 컴포넌트마다 구조가 통일되지 않고, 읽기 힘든 코드가 되어버린다.
  3. 추후 유지보수를 위해 코드에 접근했을 때, 해당 로직이 어디에 있는지 찾기가 쉽지 않다.
    (리액트는 CDD 기반이라 해당 컴포넌트를 찾으면 되는데, 그 정의가 모호하니 절차식으로 하나하나 컴포넌트를 까봐야 함)

이 모든 문제점은 초기에 컴포넌트의 역활과 책임을 생각하지 않았기에 발생하는 문제점이었습니다.
즉, 설계를 제대로 하지 않고 바로 코드부터 작성했다는 뜻이기도 하죠.

📌 컴포넌트의 역할과 책임을 분명하게 했을 때

저는 회사에서 팀원들과 다양한 코드리뷰를 주고 받으면서, 컴포넌트의 역할과 책임을 우선적으로 생각해가며 개발을 진행해봤습니다.

기존에는 무작정 페이지 컴포넌트부터 만들고 시작했던 걸, 페이지 컴포넌트의 역할과 책임을 한번 생각해보았습니다.

그래서 대략적으로 다음과 같이 컴포넌트의 역할을 생각해보았더니, 우선적으로 만들어야 하는 컴포넌트가 무엇인지 알 수 있었습니다.

예를 들어, 게시글 목록을 보여주는 페이지를 보여준다고 했을 때,

  • PageComp - UI의 구성 및 화면 배치에 대한 책임
  • PostListComp - 게시글 데이터 관리(Fetch) 및 리스트를 화면에 뿌려주는 역할
  • PostListItemComp - 각 게시글 하나하나에 대한 UI 및 수정, 삭제에 대한 책임

위 처럼 컴포넌트에 대한 역할과 책임을 분명하게 하고 개발을 시작했을 때, 다음과 같은 개선점을 확인할 수 있었습니다.

const Page = () => {
  return (
    <Header />
    <PostListComp />
    <Footer />
  )
}

const PostListComp = () => {
  const {data:postList} = useSuspenseQuery(getPostList());
  
  return (
    <div className="mt-10">
      {postList.map((post) => {
        <PostListItemComp post={post} />
      })}
    </div>
  )
}

const PostListItemComp = () => {
  return (
    <div>
      ...
    </div>
  )
}
  1. 컴포넌트의 이름만 봐도, 해당 컴포넌트 안에 어떤 로직이 들어가 있는 지 예상이 가기 때문에 중복코드를 작성할 가능성이 줄어든다.
  2. 컴포넌트의 역할과 책임을 설정했다는 것은 페이지의 구조를 미리 설계했다는 의미이기 때문에, 디벨롭을 지속적으로 해도 구조가 꼬이지 않다.
  3. 버그가 발생했을 경우에도, 버그가 발생한 기능을 컴포넌트의 이름으로도 그 위치를 쉽게 찾을 수 있기 때문에 신속하고 정확한 대응이 가능해진다.
  4. 다른 사람이 해당 코드를 읽거나 시간이 오래 지난 상황에서 그 코드를 다시 읽을 때도, 컴포넌트의 역할과 책임이 분명하기 때문에 코드를 이해하기가 쉽고, 코드 수정에 따른 사이드 이펙트 발생률이 눈에 띄게 줄어든다.

📌 느낀점

이렇게 컴포넌트의 역할과 책임을 중점적으로 생각하는 습관을 가지다보니, 개발이라는 직무를 수행함에 있어서 코드는 단순히 기능을 돌아가게 하는 역할뿐만이 아닌, 협업을 위한 문서역할을 한다는 느낌을 받았던 것 같습니다.

기획안을 만들고, 회계 장부나 보고서를 만들어서 제 3자가 봐도, 프로젝트에 대해 이해할 수 있도록 하듯이,
코드에도 그 코드를 작성한 의도가 분명하게 들어나게 하여, 다른 개발자가 봐도 빠르게 프로젝트 구조에 대해 이해하고 협업할 수 있도록 하는 것이 전체적인 개발속도를 향상시키고, 빠르게 확장시켜 나갈 수 있는 방향이라고 생각합니다.

그 방법 중 하나가 컴포넌트의 역할과 책임을 분명하게 하는 것이라는 점을 이번에 느꼈고, 앞으로 더 다양한 경험을 통해 효율적이고 좋은 개발 습관을 기르기 위해 노력할 예정입니다!

profile
2년차 프론트엔드 개발자입니다.

0개의 댓글