team logo icon

컴포넌트 분리하기

이게 재사용성이 높은게 맞나 ..?

리액트 컴포넌트를 분리하는 왜 해야하고, 기준은 무엇일까?

개발을 할 때 뷰를 보고 로직을 구상할 때 가장 고민이 되는 지점은 어떻게 해야 효율적으로 컴포넌트를 분리할 수 있을까? 인데요


제가 개발에 들어가기 앞서 습관적으로 고민하는 것들은

  1. UI적으로 재사용 가능한가

    ex) 모달창, select박스, 토글 등등 여러 페이지에서 공통적으로 쓰이는가?

    내부에 들어가는 내용들이 하나의 interface type으로 정의될 수 있는가?

  2. 뷰와 내부 로직을 분리할 수 있는가?

    ex) 로직을 담당하는 함수를 다른 파일로 분리하고, 컴포넌트 내부에는 정말 만 담당하도록 분리가 가능한가?

이렇게 두 가지를 가장 크게 고민한 후에 틀을 잡고 개발을 하는 편입니다.


하지만 이렇게 개발을 진행하더라도

  1. 명확하게 정해진 기준이 있는 것이 아니고

  2. 현재 나에게 주어진 뷰와 api에만 대응이 가능한 로직을 작성하고 있다는 생각이 늘 들었어요.

  3. 만약 기획,디자인에서 변경사항이 발생한다면 재사용성이 떨어지게 되는 경우도 발생했어요

  4. 어떨 땐 이렇게까지 분리하는게 맞는건가 싶기도, 어떨땐 이렇게까지 하나의 컴포넌트에 많은 내용이 들어가도 되는건가? 싶기도 하답니다.


컴포넌트 분리라는 것은 공부를 해도해도 명확하게 와닿지는 않는 부분인 것 같아요. 정답이 있다기보다는 알맞은 방향성과 사고하는 방식이 중요하다고 생각해요.


이번 공유과제를 알아보면서 카카오 FE 기술 블로그Toss 현재엽님의 컴포넌트 분리 방법에 관한 영상을 접하게되었어요. 이때 두 곳에서 공통적으로 정의하고있는 부분이 있어서 컴포넌트를 분리할 때의 알맞은 방향성이란 이러한 부분들이 아닐까? 라고 생각했고, 이번 공유과제에 해당 부분들에 대해 정리해보려고 합니다 !


1. Headless 기반 추상화

  • Headless란 로직과 UI 표현을 분리하여 구현하는 것을 말한다.

  • 일반적으로 리액트 훅으로 구현되며, 컴포넌트가 특정 UI를 규정하지 않고, 로직과 상태 관리만을 전적으로 책임지는 컴포넌트이다.

  • 유지보수에 편리하고, 재사용 가능한 컴포넌트를 구축할 수 있다는 이점이 있다.


  • 한쪽에서는 JSX 뷰와 상호작용하고 다른 한쪽에서는 필요에 따라 기본 데이터 모델과 통신하는 패턴이다.

  • 이 패턴은 시각적 표현에서 로직을 분리하기 때문에, UI의 동작 또는 상태 관리 측면만을 원하는 개발자에게 유용하다.


2. SOLID 원칙

개발자라면 한 번쯤은 들어봤을 SOLID 원칙, 그 중에서도 S(SRP)에 대한 이야기가 공통적으로 나왔답니다.

이 부분에 대해서는 너무너무 잘 정리되고, 현업에서의 내공이 그득그득 묻어있는 아티클을 공유드립니다 .. 그리고 그 아티클에서 가장 머리가 띵 했던 부분을 가져와보았어요 ..

프론트엔드와 SOLID 원칙 | 카카오엔터테인먼트 FE 기술블로그

(정말 강추하는 아티클입니다 !)

Single Responsibility Principle

직역하면 “단일책임원칙”입니다. 이를 섣불리 코딩 기법으로 접근하면 ‘책임=동작’ 공식으로 잘못 해석하게 됩니다. 즉, 단일한 “동작”만 가진 컴포넌트로 쪼개야 한다고 오해할 수 있습니다

→ 아티클을 읽고 가장 뜨끔하고, 머리를 쾅 맞은듯한 기분이 들었던 곳이에요.

중요한 점은 SRP의 ‘책임’이 의미하는 것을 소프트웨어 내부의 ‘동작’ 이나 ‘논리’가 아니라 조직 간 커뮤니케이션 영역으로 봐야 한다는 점입니다.

즉, SRP 원칙을 지킨다는 것은 컴포넌트를 설계할 때 “요구사항을 전달하는 책무 단위”로 설계한다는 것을 의미합니다.

여기서 말하는 책무란..

서비스 개발 그룹
├─ 기획
├─ 디자인
├─ 개발
│  ├─ 메인API
│  ├─ 섹션API


→ 정리하자면, 기획, 디자인, 서버의 요구사항에 맞게 컴포넌트의 단위를 잡아야 한다는 말이죠 !


3. 합성 컴포넌트

여기서 잠깐 ! 컴포넌트는 왜 분리해야하는걸까?

프론트엔드가 다루어야할 관심사는 정말 너무나 많다. 크게 나누어본다면

  1. UI 로직(단순 UI, 애니메이션 로직, 하드코딩적인 요소)

  2. 서버 로직(데이터 패칭, 업데이트 로직, 유저 인증인가 로직, 로딩처리, 에러처리), 로그 등

이 모든 관심사를 한 군데에 몰아둔다면 ..? 정말 방대한 양의 코드가 작성되고, 중복작성하는 코드도 많아질 것이고, 남들이 봤을 때 해당 컴포넌트가 무슨 역할을 하는지 파악하기 어렵게 되겠죠..


이렇게 관심사들을 잘 분리하기 위해서는 합성 컴포넌트가 하나의 방법이 될 수 있어요!

이번 아티클을 작성하면서 참고한 토스 유튜브 영상에 나오시는 현재엽님은 33기 앱잼 데모데이날 멘토로 오셨던 분이에요!


이 부분은 실제로 멘토님께 제가 질문 드렸던 부분입니다.

컴포넌트를 최대한 재사용하는 것이 클린한 코드라는 생각이 들어서 겹치는 부분을 최대한 찾아서 재사용성을 높이려고 하였습니다. 다만 이렇게 구현하다보니 불필요한 prop들이 많이 전달되기도 하고, 로직과 뷰의 분리가 명확하지 못해지는 듯한 느낌을 받았습니다.

조금 겹치는 코드 혹은 컴포넌트가 발생되더라도 로직과 뷰의 독립성을 높이는 것이 좋을지 중복된 코드를 줄이고 내부에서 상태 전달을 통해 작업하는 것이 더 좋을지에 대해 궁금합니다. (이렇게 하게 되면 의존성이 높아진다고 생각하긴 합니다 .. )


이에 대한 답변으로는 ,,

“props가 너무 많이 내려간다? 그러면 분리를 하지말고 하나의 컴포넌트에 몰아두세요. 그러면 이제 너무 많은 것을 모아두게 되니까 서버 api 통신과 구분하여 구현하세요. 이때는 children으로 합성하면 돼요. 더 자세한 내용은 제 블로그와 유튜브에 올라가있어요.”


합성 컴포넌트 패턴은 여러 개의 작은 컴포넌트들이 각각의 역할을 분담하도록 하고 이를 조립하여 하나의 큰 컴포넌트를 만드는 것이라고 할 수 있습니다.

장점은 컴포넌트를 사용할 때 개발자가 필요로 하는 서브 컴포넌트만 합성하여 사용할 수 있기 때문에 개발자에게 자율성을 줄 수 있다는 것과 하나의 컴포넌트 안에 수많은 Props를 한꺼번에 전달하지 않고 서브 컴포넌트에 적절히 분배하여 관심사를 분리할 수 있다는 것입니다.

반면, UI에 대한 자유도가 높은만큼 컴포넌트의 의도대로 합성되지 않을 수도 있고 합성 컴포넌트 패턴을 사용하지 않았을 때보다 JSX 소스 코드 길이가 길어질 수 있다는 단점도 있습니다.



참고자료

(현업에서 쓰이는 코드 예시들이 많으니 읽어보시는 걸 추천드립니다 🤗)

https://www.youtube.com/watch?v=fR8tsJ2r7Eg

https://fe-developers.kakaoent.com/2023/230330-frontend-solid/

https://fe-developers.kakaoent.com/2022/220505-how-page-part-use-atomic-design-system/

https://fe-developers.kakaoent.com/2022/220731-composition-component/


최신 아티클
lighthouse에 대해
문성희
|
2024.05.13
lighthouse에 대해
lighthouse에 대해
prettier, eslint, styleLint에 대해
이진
|
2024.05.10
prettier, eslint, styleLint에 대해
4주차 공유과제
Article Thumbnail
박채연
|
2024.05.10
Prettier, ESLint, StyleLint
prettier, eslint, stylelint