반응형

새벽 2시, 우리 프로젝트 React 컴포넌트 200개가 한꺼번에 뒤집어졌을 때 — 그때

프로젝트 마감이 코앞인데 갑자기 화면이 안 뜹니다. 새벽 2시, 노트북 앞에서 30분째 멍하니 앉아 있던 순간이 떠올라요. 그날 제가 React 컴포넌트 설계 패턴 정리를 진심으로 시작했습니다.


제 React 컴포넌트 설계 패턴 정리 이야기: 시작부터 현재까지

처음엔 그냥 "되면 된다"라는 마인드로 코드를 짰습니다. 진짜 그랬어요. 한 컴포넌트 파일에 비즈니스 로직, 뷰, API 호출을 다 몰아넣고, props를 10개씩 넘기면서도 별 문제 없다고 생각했죠.

돌이켜보면, 그때는 "작동하는 코드"와 "유지보수하는 코드"의 차이를 몰랐던 것 같습니다. 컴포넌트가 50개를 넘어가면서부터 재사용이 불가능해졌고, 비슷한 UI를 만들 때마다 Ctrl+C, Ctrl+V로 복붙을 시작했고, 그러다 props 이름이 조금씩 달라지면서 버그가 슬슬 생기기 시작했어요.

React 프로젝트에서는 신규 개발자가 첫 주에 마주치는 컴포넌트의 평균 개수가 적지 않은 편으로 알려져 있습니다. 제 프로젝트도 예외는 아니었어요. 새로 합류한 사람이 코드를 읽을 때 어디서부터 시작해야 할지 몰라 헤매는 일이 잦아졌죠.


이런 일이 일어난 진짜 원인

핵심 원인은 단 하나였습니다. 컴포넌트가 너무 많은 책임을 지고 있었다는 점이에요.

공식 문서를 확인하면 React는 "단일 책임 원칙"을 강조합니다. 한 컴포넌트는 한 가지 일만 해야 한다는 거죠. 재사용 가능한 컴포넌트는 독립적으로 테스트 가능하고, 명확한 인터페이스를 가져야 한다는 권고도 같은 맥락에서 나옵니다. 제 코드는 이 두 가지 다 충족하지 못하고 있었습니다.

구체적으로는 이런 문제가 있었습니다.

  • 한 파일에 300줄짜리 컴포넌트가 너무 많음
  • props drilling이 5단계 이상 깊어짐
  • 같은 로직이 여러 컴포넌트에 중복해서 들어감
  • 상태 관리가 각 컴포넌트 안에 흩어져 있어서 디버깅이 지옥이었음

제가 결국 찾은 해결 방법

결국 패턴을 정리하면서 두 가지 접근법을 비교해 봤어요. 옵션 A: HOC(고차 컴포넌트), 옵션 B: 커스텀 훅(Custom Hooks). 두 패턴의 비교는 아래 표로 정리했습니다.

비교 항목 HOC (고차 컴포넌트) 커스텀 훅 (Custom Hooks)
도입 시기 React 0.13 이후 React 16.8 이후
코드 형태 컴포넌트를 반환하는 함수 일반 함수 (use 접두사)
가독성 Wrapper 컴포넌트 중첩으로 복잡해질 수 있음 평범한 함수 호출이라 직관적
상태 공유 props로 전달 (구조가 깊어질 수 있음) 훅 안에서 직접 공유
디버깅 React DevTools에서 Wrapper가 끼어들어 추적 어려움 함수 호출 스택 그대로 추적 가능
권장 시점 레거시 코드 유지보수 신규 코드, React 16.8 이후 환경
타입 추론 제네릭 작성 난이도 있음 비교적 단순

표에서 보듯 정답은 상황에 따라 다르다입니다. 다만 React 18.2 기준 공식 릴리스 노트에서도 "함수형 컴포넌트와 훅을 우선 권장한다"는 흐름이 분명해요. React 19가 나온 지금도 그 기조는 유지되고 있습니다. 제 프로젝트도 결국 HOC를 걷어내고 커스텀 훅으로 대부분 옮겼습니다.

GitHub 이슈 트래커에 따르면 facebook/react 저장소에서도 HOC의 Wrapper Hell 문제와 관련된 여러 이슈가 오랫동안 논의되어 왔다고 합니다. 실제 React 진영도 훅 도입 이후 HOC 사용을 줄이는 쪽으로 움직이고 있다는 뜻이에요.

💡

핵심 요점: 신규 프로젝트라면 처음부터 HOC 대신 커스텀 훅 + 함수형 컴포넌트로 시작하세요. 레거시 코드를 다룰 때만 HOC 패턴을 유지하는 게 정신건강에 이롭습니다.


이번 경험에서 얻은 3가지 교훈

첫째, 한 컴포넌트는 한 가지 일만 하게 하세요. 처음부터 분리하기 귀찮아도, 분리해 두면 나중에 디버깅할 때 시간을 아낍니다.

둘째, props drilling이 3단계 이상 깊어지면 Context API나 상태 관리 라이브러리를 검토하세요. props만으로 해결하려 들면 결국 컴포넌트 간 결합도가 높아져서 테스트가 힘들어집니다.

셋째, 같은 로직이 두 군데 이상 보이면 무조건 훅으로 빼세요. "나중에 정리하면 되지"라는 말이 가장 위험합니다. 그 "나중"은 보통 오지 않거든요.

참고로, 이 세 가지 원칙은 단순히 제 경험뿐 아니라 React 커뮤니티 전반에서 자주 언급되는 권장 사항입니다.


마무리

정리하면, 컴포넌트 설계 패턴은 결국 "책임을 어떻게 나눌 것인가"의 문제입니다. 작은 프로젝트일수록 미리 패턴을 정해두는 게 후회 없이 가는 길이에요.

오늘은 여기까지. 도움이 되셨으면 좋겠네요. 패턴 적용 중에 막히는 부분이 있으면 댓글로 알려주세요. 같이 고민해 보겠습니다.


자주 묻는 질문 (FAQ)

Q. HOC 패턴을 아직도 써야 하나요? A. 신규 프로젝트라면 권장하지 않습니다. React 16.8 이상 환경이면 커스텀 훅이 더 깔끔해요. 단, 외부 라이브러리가 HOC로 감싸 제공된다면 그건 그대로 쓰는 게 편합니다.

Q. 커스텀 훅과 Context API, 언제 나눠 쓰나요? A. 로직 재사용 목적이면 커스텀 훅, 전역 상태 공유 목적이면 Context API를 떠올리시면 됩니다. 둘을 함께 쓰는 것도 흔한 조합이에요.

Q. 클래스 컴포넌트는 이제 안 배워도 되나요? A. 신규 프로젝트에선 거의 쓰지 않습니다. 다만 레거시 코드를 유지보수할 일이 있다면 lifecycle 메서드 정도는 알아두셔야 해요.

Q. React 19에서도 같은 패턴이 유효한가요? A. 큰 틀은 그대로 유효합니다. 다만 서버 컴포넌트, use() 훅 등 새로운 개념이 추가됐으니 추후 별도로 정리할 계획이에요.

Q. 컴포넌트 분리 기준이 명확하지 않을 때는요? A. "이 컴포넌트가 어떤 props를 받는지 1분 안에 설명할 수 있느냐"를 자문해 보세요. 설명이 길어지면 분리 신호입니다.


#리액트 #컴포넌트설계 #React훅 #HOC #프론트엔드

반응형
Posted by no_name
:
반응형

React 컴포넌트 설계 패턴, 반년 동안 삽질하고 정리한 이야기

리액트 프로젝트 처음 맡았을 때, 컴포넌트를 그냥 마구 만들어서 3개월 만에 코드베이스가 스파게티가 됐어요. 그때부터 진짜 설계 패턴 공부를 시작했습니다. 오늘은 제가 직접 부딪힌 경험을 솔직하게 풀어볼게요.

제 React 컴포넌트 설계 패턴 정리 이야기: 시작부터 현재까지

사실 처음엔 컴포넌트 = 그냥 함수라고 생각했습니다. 버튼 하나 만들었는데, 거기에 비즈니스 로직이랑 스타일, API 호출까지 다 들어가 있더라고요. 간단합니다. 그게 시작이었습니다.

그러다 프로젝트가 커지면서 이런 일이 벌어졌어요.

  • props가 20개 넘어가는 컴포넌트 등장
  • 같은 UI를 3군데서 다르게 렌더링
  • 상태가 어디서 오는지 추적 불가능
  • 재사용하겠다고 만든 컴포넌트가 한 군데서만 쓰임

스택오버플로우 답변에 따르면 이런 현상은 "Prop Drilling"과 "God Component"라는 이름으로 자주 언급됩니다. stackoverflow.com/questions/38357241 같은 글에서 실제로 같은 상황을 호소한 사람이 많았어요.

그때는 몰랐는데, 돌이켜보면 패턴을 모른 게 아니라 적용 타이밍을 몰랐던 거였어요.

이런 일이 일어난 진짜 원인

원인은 단순했습니다. 처음에 설계를 안 했거든요.

공식 문서를 확인하면 React 팀은 "Thinking in React" 가이드에서 먼저 컴포넌트 계층을 쪼개라고 강조합니다. (출처: https://react.dev/learn/thinking-in-react) 근데 저는 VSCode 켜고 바로 App.jsx부터 작성했어요. 솔직히 후회됩니다.

또 하나. React 18로 업그레이드하면서 Suspense와 Concurrent Features가 추가됐는데, 이걸 모른 채 코드를 짰습니다. 공식 릴리스 노트에 따르면 React 18은 2022년 3월 29일 출시됐고, 자동 배칭(Automatic Batching)이 기본값으로 들어왔어요. 출처: https://react.dev/blog/2022/03/29/react-v18

⚠️

설계 없이 코드를 먼저 짜면, 나중에 리팩토링 비용이 10배 이상 증가합니다. 체감상 진짜 그랬어요.

제가 결국 찾은 해결 방법

저는 결국 5가지 패턴을 비교해 보고, 우리 프로젝트에 맞는 조합을 골랐습니다. 표로 정리합니다.

패턴 장점 단점 적합한 상황
컨테이너/프레젠테이셔널 관심사 분리 명확 보일러플레이트 증가 데이터 fetch와 UI 분리
컴파운드 컴포넌트 유연한 API 제공 학습 곡선 있음 셀렉트, 아코디언 같은 복합 UI
고차 컴포넌트 (HOC) 횡단 관심사 재사용 props 충돌 가능 권한 체크, 로깅
렌더 프롭스 명시적 데이터 흐름 JSX 중첩 깊음 동적 렌더링이 필요한 경우
커스텀 훅 상태 로직 재사용 남발 시 복잡도 증가 React 16.8 이후 거의 모든 케이스

참고로 MDN 웹 문서를 확인하면 React 자체는 라이브러리라서 정해진 패턴이 따로 없습니다. 그래서 팀 컨벤션이 핵심이에요. 한 번 정해두면 오래 갑니다.

저는 결국 컴파운드 컴포넌트 + 커스텀 훅 조합으로 정착했습니다. 이유는 단순해요. React 19에서도 잘 동작하고, 훅 기반이라 트리 쉐이킹이 잘 됩니다. React 19는 2024년 12월 5일 정식 출시됐어요. 출처: https://react.dev/blog/2024/12/05/react-19

한 번 해보세요. props 개수가 눈에 띄게 줄 겁니다.

이번 경험에서 얻은 3가지 교훈

교훈 1. 처음 30분은 설계에 쓰자.

타이핑 시작 전에 컴포넌트 계층도를 그립니다. 종이에요. 도구 없어도 됩니다. 사실 이게 진짜 효과 있었어요.

교훈 2. 작은 컴포넌트부터 쪼개자.

100줄짜리 컴포넌트 보면 일단 의심하세요. 대부분 더 쪼갤 수 있어요. 살짝만 분리해도 테스트하기 쉬워집니다.

교훈 3. 패턴은 도구일 뿐, 답이 아닙니다.

커스텀 훅이 좋다 해서 모든 곳에 적용하면, 오히려 추적이 더 어려워집니다. 그러면 안 되죠. 팀 규모와 프로젝트 성격을 고려해야 합니다.

💡

핵심 요점: 패턴은 "이 상황에서 이렇게 쓰면 편하다"는 도구 모음일 뿐, 맹신하면 독이 됩니다.

마무리

오늘은 React 컴포넌트 설계 패턴을 반년 동안 부딪히며 정리한 이야기를 풀어봤습니다. 한 줄로 요약하면 이래요. "설계 30분, 구현 2시간" — 이 비율이 진짜 효과 있었어요.

여러분의 프로젝트는 어떤 비율인가요? 댓글로 알려주시면 저도 많이 배울 수 있습니다. 끝까지 읽어주셔서 고맙습니다. 도움이 되셨으면 좋겠네요.


자주 묻는 질문 (FAQ)

Q. React 18과 19 중 어떤 버전에서 시작하는 게 좋을까요? A. 2025년 기준 신규 프로젝트는 React 19로 시작하는 걸 추천합니다. 자동 메모이제이션과 Actions가 추가되어 보일러플레이트가 크게 줄었어요.

Q. 커스텀 훅과 유틸 함수의 차이는 무엇인가요? A. 커스텀 훅은 React 상태나 생명주기를 사용할 수 있는 반면, 순수 유틸 함수는 일반 자바스크립트 함수입니다. 상태가 필요 없다면 유틸 함수로 충분해요.

Q. 컴파운드 컴포넌트 패턴은 언제 쓰나요? A. 셀렉트 박스, 탭, 아코디언처럼 부모-자식 관계가 명확한 UI에 적합합니다. 페이스북, 유튜브 셀렉트 박스가 대표적 사례죠.

Q. 고차 컴포넌트는 이제 안 쓰나요? A. React 공식 문서도 훅 사용을 권장하지만, 횡단 관심사(로깅, 권한 체크)에는 여전히 유효합니다. 무조건 배제하진 마세요.

Q. 클래스 컴포넌트는 배워야 하나요? A. 레거시 코드 유지보수라면 알아야 하지만, 신규 프로젝트는 함수형 컴포넌트로 충분합니다.

#리액트 #React #컴포넌트설계 #프론트엔드 #웹개발

반응형
Posted by no_name
: