Frontend Fundamentals 모의고사는 토스에서 실제로 출제되었던 과제에 참여하면서 토론하고 해설을 들을 수 있는 프로그램이다. 링크드인에서 이런 프로그램을 진행한다는 것을 보고 선착순 50명 안에 들기 위해 알람을 맞춰놓고 기다렸다.
올해 초, Frontend Fundamentals 문서를 읽고 회사에서도 개인 프로젝트에서도 어떤 코드가 더 좋을까에 대해서 많이 고민하고 개선할 수 있었다. 이번 기회로 토스에서 코드를 작성할 때 중요하게 생각하는 부분이 어떤 것인지 더 많이 배우기를 기대하며 모의고사에 참여했다.
먼저 간략하게 느낀점부터 적어보자면,
1. 과제를 풀면서 평소에 고민하던 부분들을 많이 마주할 수 있어서 좋았다.
2. 제출 후에는 다른 참여자들의 코드를 보면서 좋은 구현 아이디어도 얻어가고, 다른 분들은 어떤 걸 중요하게 생각하며 코드를 작성하는지도 엿볼 수 있었다.
3. 라이브 해설강의가 수능 모의고사 풀이 강의를 떠오르게 했는데, 무릎을 탁치게하는 깨달음도 얻고 나도 나름 Frontend-fundamentals에서 배운 점들을 잘 써먹고 있구나 싶은 자신감도 생겼다.
처음 과제를 받았을 때, 요구사항의 기능 구현 난이도가 높지는 않아보였고 확장성을 고려한 설계와 추상화 관점에 집중해달라는 문구가 있었다.
그래서 익숙한 기술들을 사용해서 기능은 빠르게 구현하고, 설계에 고민을 많이 해보자는 마음으로 시작했다.
폼 상태 관리, 필터링 로직 가독성 고민 같은 부분도 있었지만 추상화가 주요 고민이었다.
여러 입력 필드들, 탭 전환, 리스트 등 별 생각 없이 구현하다보면 그냥 관성적으로 컴포넌트로 분리할까? 싶은 부분들이 있었다.
하지만 이번 만큼은 이유 없이 추상화 하지 않겠다고 다짐하며 고민 끝에 나름의 기준을 세울 수 있었다. 고민을 하며 세운 정말 나름의 기준이고 정답은 아니다.
여러 입력 필드들이 있고, 이 입력 필드들은 연관된 상태를 가지기 때문에 하나의 form state로 다루는 상황이었다. 이 필드들을 form이라는 컴포넌트로 추상화할지 고민되었다. 그래서 일단 컴포넌트를 만들어보니 몇가지 문제점이 눈에 보였다.
<Spacing />으로 필드사이 간격을 조정하고 있었는데, 하나의 form으로 묶어보니 페이지 컴포넌트에서 레이아웃이 전혀 보이지 않았다. 이 3가지 문제점을 보고 필드별로 추상화하기로 결정했다.
여기서 추상화를 안 할순 없었냐하면, 그럴수도 있었지만 입력 필드 로직, 스타일 등이 모두 페이지 컴포넌트에 존재했기 때문에 이 입력 필드 하나만을 위한 코드들은 숨기는게 좋다고 생각해서 추상화는 꼭 필요하다고 생각했다.
탭 전환을 위한 UI 컴포넌트를 탭 내용을 렌더링 하는 기능까지 갖춘 컴포넌트로 추상화할지가 다음 고민이었다.
하지만 이를 추상화 해서 얻는 점은 탭 렌더링 로직을 숨긴다 정도인데 탭 UI는 있으니 상태만 관리하고 조건부 렌더링을 하면 되는 건데 이걸 숨겨야할까? 싶었다.
그리고 UI 컴포넌트의 인터페이스를 변경하지 않고 최대한 활용하는게 일관성 있게 쓸 수 있을 거라 생각하여 페이지 컴포넌트에 탭 렌더링 로직을 드러냈다.
제가 올린 PR에도 언제든 편하게 의견 주시면 좋아요~
모든 분의 PR을 다 보고 싶었지만 게으름 이슈로 다 보지는 못했다.
점심시간에 잠깐 짬을 내서 코드 리뷰도 달아보고 여러 아이디어를 얻어보았다.
기억에 남는 아이디어는 nummeric input을 다루는 hook을 통해 포메팅과 상태 로직을 추상화 한 것이었는데, 그냥 util로 만들어서 상태 변경 때마다 포메팅 하는 것보다 훨씬 좋다고 생각했다.
그리고 "단일 책임" 경계에 대한 discussion도 아주 재미있었다.
라이브코딩으로 진행해주신 해설을 통해 요구사항을 분석하고 접근하는 법부터 설계의 관점을 배울 수 있었다.
해설을 통해 배운점, 잘 해왔던 점을 정리해본다.
// 이렇게 단순한 상태만 관리하는 훅이지만
// 이 내부 구현이 전역 상태가 될지, storage를 사용할지, reducer를 사용할지, setQueryState를 사용할지 등
// 구현 방식의 선택사항일 뿐, 단순하니 추상화할 가치가 없다고 생각하지말자.
function useView(...) {
const [view, setView] = useState<"view1" | "view2>(...)
return [view, setView] as const
}
오늘을 계기로 코드를 보는 시각이 달라질 것 같다. 많은 고민과 연습이 필요하겠지만 좋은 코드의 기준들이 체화되도록 노력해야겠다.
좋은 시간 만들어주신 토스 프론트엔드 개발자 분들께 감사드립니다!