
https://tosspublic.notion.site/frontend-fundamentals-mock-exam-25-11
Frontend Fundamentals 모의고사 (25.11) | Notion
Frontend Fundamentals 모의고사?
tosspublic.notion.site
나는 배운 것을 적용하고 피드백하며 개선해 나가는 과정이 중요하다고 생각하는데 한동안 그럴 수 있는 기회가 부족했다.
그러던 중 Toss Frontend Fundamentals 모의고사를 알게 되었고 운이 좋게 시험에 응시하고 해설 강의까지 들을 수 있는 기회가 주어졌다.
모의고사 진행
꼭 정해진 시간 내 제출해야 한다는 규정은 없었지만, 나는 실전 감각을 늘리기 위해 실제 제출 시간에 맞춰 진행을 했다.
지금까지 받아봤던 토스 과제중에서 난이도는 가장 쉬운 편이었지만 그럼에도 리팩토링까지 완벽하게 하기엔 시간이 부족했다.
이슈
코드를 작성하면서 잠깐 막혔던 부분은 두 곳이 있었다.
1. 기계적으로 tanstack query를 세팅하면서 `QueryClientProvider`에 주입하는 queryClient를 컴포넌트 내부에서 실행했다. -> 렌더링 될 때 마다 초기화
2. 세 자리 단위로 콤마(,) 출력

gif에 보이는 것처럼 입력하는 값에 세 자리 단위로 콤마를 출력해야 하는 요구 사항이 있었다.
처음에는 아무 생각없이 useState에 사용해서 상태를 연동해 줬고, 여기에 toLocaleString을 붙여줬는데 의도대로 동작하지 않았다.
이때 string, number간 타입 변환을 뭉게 버린 것이 문제라고 판단하고, 아래와 같은 흐름으로 문제를 파악하고 해결했다.
- toLocaleString은 number값을 string로 변환한다.
- 금액 상태는 number로 관리되어야 유지보수에 용이하다.
- ui 상태는 콤마를 사용하기 위해 string으로 사용되어야 한다.
->
const [state, setState] = useState(0);
const onChange = (value: number) => setState(value);
<Input
label="목표 금액"
placeholder="목표 금액을 입력하세요"
suffix="원"
value={state.toLocaleString() ?? ''}
onChange={e => onChange(Number(e.target.value.split(',').join('')))}
/>
리팩토링
리팩토링에서 중점적으로 처리한 부분은 관심사 분리와 비즈니스 로직 분리이다.
page.tsx에서는 뷰 컴포넌트의 내부 구현을 알 필요가 없고 최대한 직관적인 인터페이스를 통해서 연결하도록 만들고자 했다.
그리고 여기서 비즈니스 로직은 UI와 분리하고자 하였는데, 바로 눈에 안 보이기도 하고 많은 시간을 투자할 수 없어 일단 모든 로직을 하나의 훅에서 불러와서 사용하는 형태로 만들었다 (container presentational 패턴이 떠오른 것 같다.)
해설 강의
하지만 해설 강의를 듣고 난 후 생각이 바뀐 부분이 있다.
UI와 코드가 1:1로 매핑되어야 유지보수에 용이하다는 이야기였는데, 이렇게 생각할 수 있을 줄은 정말 몰랐다.
나는 하나의 관심사로 묶을 수 있는 컴포넌트들은 다 묶어 응집도를 높이고자 하였는데, 무조건 합치는 게 좋지만은 않다는 것이다.
또한 내 코드를 베이스로 리뷰도 해주셨는데 매우 영광스러웠다.
내 코드에서만 두가지 이야기를 들을 수 있었는데
첫 번째는 관심사 분리에 대한 이야기였다.
현재 만들어진 훅에 관심사 분리가 필요하다고 생각은 했지만 시간이 있었어도 재엽님처럼 그렇게 잘 나누지는 못했을 것 같다.
재엽님께서는 응집도 측면에서 관련 코드는 최대한 가까이 있어야 한다고 말씀해주셨다.
(나는 frontend fundamentals의 이 글을 보기 전까지 container presentational 패턴에서 custom hook을 container에서 불러와서 사용하는 방식을 오래 사용해왔는데, 빠르게 코드를 작성하다면 어느 순간 이 패턴을 따라가고 있다. 재엽님께서 해주신 말씀이 이것을 벗어나는 데 많은 도움이 될 것 같다.)
- 몬스터 훅은 추상화가 아니라 추출이다.
- 추출이 아니라 추상화를 해야 한다.
- 추상화는 각각의 역할이 맞춰진 인터페이스를 디자인하는 것이다.
- 중요하지 않은 것은 숨기고 중요한 것은 드러내야 한다.
두 번째는 추상화에 대한 이야기였다.
아래 내용은 확실한 건 아닌데 지금까지 이해한 바로는
추상화를 한다면 = 컴포넌트를 분리한다면 일반적인 인터페이스를 가져야 한다는 것이다.
그렇기에 보통 ~Form, ~Card, ~Input와 같이 일반적인 네이밍을 사용해야 하는 것 같다.
공감이 되는 부분도 있었다.
책임 단위로 추상화를 하면 재사용성은 자연스럽게 따라온다는 이야기였다.
단순 Input 컴포넌트나 Button 컴포넌트가 아닌 이상 "이거 재사용 가능한 컴포넌트로 만들 거야"하고 만든 컴포넌트는 오히려 생산성을 낮추고 유지보수를 어렵게 하는 경우를 종종 봤기 때문이다.
마치며
오랜만의 가파른 성장의 시간이었다.
알고 있는 내용도 많았지만, 알고 있는 것과 잘 적용할 수 있는 것은 다르다는 것을 다시 한번 깨달았다.
지금까지 배운 내용을 기반으로 동일한 과제를 다시 풀어봐야겠다.
'회고' 카테고리의 다른 글
| AI 데이터센터 서비스 TECH 세미나 후기 (0) | 2025.11.01 |
|---|---|
| 프론트엔드 다이빙 클럽 회고 (0) | 2025.02.08 |
| 당근 면접 후기 (17) | 2023.12.23 |
| 교내 학술제 발표 회고 (0) | 2023.11.30 |
| 해군 사이버작전센터 회고 (6) | 2022.04.12 |