이번 글은 Toss Frontend Fundamentals 문서를 읽으며 정리한 내용을 기록한 글이다.
정리 과정에서 특히 아래 글/자료들이 인사이트를 주었다:
단순 요약보다는, 실제로 내 코드에 적용해보며 느꼈던 고민 중심으로 풀어본다.
💡 코드 품질을 판단하는 네 가지 기준
토스에서는 코드 품질을 판단할 때 다음 네 가지를 핵심으로 본다:
가독성: 얼마나 쉽게 읽히는가?
예측 가능성: 이름만 보고도 어떻게 동작할지 알 수 있는가?
응집도: 관련된 것들이 가까이 모여 있는가?
결합도: 불필요하게 많은 맥락이 엮여 있지는 않은가?
1. 가독성 – 코드는 결국 '읽는 사람'을 위한 것
같이 실행되지 않는 코드는 같이 안 보이게 하기
- 조건문이나 분기 로직은 분리해서 읽는 맥락을 줄이자
- 예:
if안에 JSX 넣는 것보다, 조건에 이름을 붙여 위로 올리는 게 읽기 쉬움
// Before
{isLoggedIn && user.isAdmin && <AdminDashboard />}
// After
const shouldShowAdmin = isLoggedIn && user.isAdmin;
{shouldShowAdmin && <AdminDashboard />}구현 상세 추상화 (HOC vs Wrapper)
- HOC: 로직 재사용에 유리. 추상화되어 있으므로 구조 파악은 어렵지만 깔끔함
- Wrapper: JSX 구조에 드러나므로 흐름이 명확함
- 목적에 따라 선택. UI 흐름 중심이면 Wrapper, 비즈니스 로직이면 HOC가 자연스러움
선언형 코드도 '적절한 수준'이 중요함
- 무조건 추상화하면 유지보수에 오히려 독이 됨
- SignUpForm 예시처럼 다양한 변형이 필요한 컴포넌트는 추상화보다 명시적 표현이 낫다
복잡한 조건엔 이름을 붙이자
isEmpty,shouldShowTooltip,isUnauthorizedUser처럼 이름을 붙이면 코드 이해도가 확 올라감- 조건 렌더링도
if (조건) return null→if (shouldSkipRender)같은 식으로 바꾸면 한눈에 읽힘
매직 넘버 없애기
300,24 * 60 * 60 * 1000같은 값은 상수로 추출해서 의미를 드러내자TIME_MS.DEBOUNCE.SEARCH,FIVE_MINUTES식으로 쓰면 나중에 고칠 때도 훨씬 쉬움
위에서 아래로 읽히는 구조로 정리
- 에러 메시지, 조건 로직은 상단에서 미리 분리해서 정의
- 하나의 흐름이 위→아래로 떨어지게 하면 훨씬 덜 헷갈림
2. 예측 가능성 – 코드를 보며 '예상'할 수 있어야 한다
이름 겹치지 않게 관리하기
- 같은 이름(
http)을 여러 레벨에서 쓰면 혼란 httpService,httpLibrary처럼 역할이 드러나게 구분하자
같은 훅은 같은 구조로 반환하기
useQuery로 만든 훅은 query 객체를 반환하는 걸 팀 규칙으로 정하면 예측이 쉬움
Discriminated Union으로 유효성 검사 구조화하기
// 타입
{ ok: true } | { ok: false; reason: string }
- 이렇게 해두면 조건 분기 시 타입이 자동으로 좁혀지고 실수 방지됨
- Basarat 글 참고
숨은 로직 드러내기
async function fetchBalance() {
const balance = await http.get<number>("...");
logging.log("balance_fetched");
return balance;
}
- 이런 식으로 부수효과가 숨어있으면 안 됨 → 별도 함수로 빼고 호출 구조 명확히 드러내자
3. 응집도 – 관련된 건 함께 묶자
자주 같이 수정되는 파일은 같은 폴더에
Form.tsx,Form.styles.ts,Form.types.ts,Form.test.tsx는 같은 폴더에 있어야 자연스럽다
매직 넘버도 상수화해서 같은 맥락 안에 두기
- 시간 상수, UI 딜레이 값 등은 의미 있는 네이밍과 함께 모듈화
한글 변수명도 상황에 따라 유효하다
- 예:
isGFSC→국가지방자치단체_공공단체_금융사_여부 - 도메인 맥락이 중요한 경우 오히려 한글이 더 명확하다 (토스 사례)
4. 결합도 – 책임은 나눌 수 있을 만큼 나누자
훅 하나에 너무 많은 걸 담지 말자
- 이미지 업로드, 유효성 검사, 상태 관리, API 호출은 역할별로 나누자
- 훅끼리 나누면 테스트도 쉬워지고 재사용성도 올라감
중복을 피하려다 더 망치는 추상화를 피하자
- 복잡한 추상화보다 차라리 중복이 낫다
- hoilzz 블로그 참고
Props Drilling 해결할 땐 Context나 query param 활용
- 깊게 props 전달할 때는 Context로
- 페이지 간 상태 공유는 query param이 더 명확할 수도 있음
결론: 코드 품질은 작은 선택의 반복이다
코드 품질을 한 번에 확 높이긴 어렵지만,
- 조건에 이름 붙이기
- 상수 분리하기
- 함수 분리해서 책임 명확히 하기
이런 사소해 보이는 선택들이 쌓여서 진짜 좋은 코드가 만들어진다.
그리고 그 판단의 기준은 결국, 내가 아닌 다른 사람이 이 코드를 보고 바로 이해할 수 있느냐다.
"좋은 코드는 결국 '덜 생각하게 만드는 코드다.'"
앞으로도 이 4가지 기준(가독성 / 예측 가능성 / 응집도 / 결합도)을 기준 삼아, 내 코드를 계속 점검하고 정리해나가고 싶다.
