[네이버부스트캠프 웹・모바일 10기] 멤버십 9주차 회고
- 네이버부스트캠프
- 회고
들어가며
부스트캠프를 하며 지금까지는 주춤한 적이 거의 없었다. 뭐든 갈아넣으면 된다는 생각이었고 실제로 그렇게 해왔다. 점점 많아지는 요구사항 속에서도 주말 시간을 투자하며 따라잡을 수 있었다. 하지만 이번 미션은 달랐다. 백엔드의 다양한 요구사항이 모두 처음이라 어디서부터 시작할지 막막했고, 방대한 내용 속에서 어디까지 어떻게 학습해야 하는지를 고민하다 집중이 잘 되지 않아 머리만 아파왔다.
혼자서는 도저히 헤쳐나갈 수 없다고 느꼈을 때, 오프라인에서 만난 캠퍼 한 분이 떠올랐다. 처음 웹개발을 배우면서도 성실하게 임하시는 모습이 인상적이었던 분이다. 용기를 내어 슬랙 디엠으로 고민을 털어놓자 그분은 노션에 하고 싶은 말씀들을 정리해서 공유해주셨다.
미션이 아니라 학습을 남기기로 하다
그분이 정리해주신 글을 한 줄 한 줄 읽으며 지난 캠프 생활을 돌아보게 되었고, 마음가짐의 차이를 크게 느꼈다. 나는 지금까지 미션을 달성하는 데 초점을 맞추어 움직였고, 계획을 세우고 목표를 달성하기 위해 달려왔지만 학습은 구현의 수단일 뿐이었다. 반면 그분은 부스트캠프를 학습을 위한 보조장치로 활용하고 있었다. 미션은 그저 학습 키워드를 던져주는 장치일 뿐 모든 요구사항을 만족시킬 필요는 없다는 말이 인상 깊었고, 캠프가 끝나고 남는 것은 설명할 수 없는 코드로 가득 찬 프로젝트가 아니라 학습한 내용이라는 말이 마음에 깊이 남았다.
그렇다면 나는 캠프가 끝나고 무엇을 남길 수 있을까. 매번 회고를 했다고 생각했지만 정작 미션이라는 틀 안에 갇혀 있었던 것 같다. 아쉬움도 있지만 지금부터라도 잘할 수 있다는 마음이 생겨 기뻤다. 이제는 모든 걸 챙기려 하기보다 꼭 필요한 것을 확실히 챙기기로 했다. 막혀 있던 길이 트인 기분이었고, 다음 주엔 다시 더 열심히 해볼 수 있을 것 같다.
각자의 방식으로 성장하는 사람들 곁에서
오프라인에서는 모두의 학습 방식이 정말 다양했다. 마스터클래스 실습을 제시간에 완성하지 못했다며 같은 테이블의 인원들끼리 함께 다시 실습을 이어가는 모습이 인상적이었고, 하나의 과제를 두고 세 시간 넘게 함께 고민하고 토론하는 모습에서 오프라인만의 특별함이 느껴졌다. 모두가 각자의 방식으로 성장하고 있다는 것이 분명히 느껴졌는데, 어느덧 다음 주면 마지막 오프라인이다. 이 소중한 시간을 어떻게 보내야 할지, 오프라인에서만 느낄 수 있는 경험이 무엇일지 곰곰이 고민해보려 한다.
팀 동료들과는 모두가 같은 부분을 구현하고 있어 함께 이야기할 주제가 많았고 다양한 방법을 공유할 수 있었다. 그룹원분들 모두가 정말 열정적이었는데, 특히 다른 그룹원의 발표를 들으면서 동시에 필기까지 하시던 캠퍼의 모습이 인상 깊었다. 같은 주제를 다루더라도 각자의 관점과 해석이 달라서 그 고민의 과정 자체가 무척 흥미로웠고, 각자의 강점을 모아 하나의 설계 문서를 만들어보면 설계 시 고려해야 할 점들이 더욱 명확해지지 않을까 하는 생각이 들었다.
복잡한 상태의 의미를 useReducer로 직접 확인하다
이번 주에는 리액트의 상태 관리 방법을 학습하고 각각의 방식을 비교해보았다. 기존에는 필터 검색창 구현을 위해 useState와 useContext를 사용했지만, 마스터클래스에서 useReducer를 새롭게 접했다. 복잡한 상태를 다룰 때 주로 사용한다고 하는데 그 '복잡한 상태'가 구체적으로 무엇이고 어떤 변화가 생기는지 궁금해, useState로도 충분히 관리할 수 있을 것 같은 상태를 굳이 useReducer로 바꿔가며 직접 도입해보았다.
useState를 사용할 때는 로직을 컴포넌트 외부로 분리하고 싶어도 setter 함수에 묶여 구조적으로 한계가 있었다. 하지만 useReducer를 사용하니 reducer 함수를 컴포넌트 밖에서 정의할 수 있어 전체 구조가 훨씬 명확해졌다. 현재 관리하는 세 개의 상태와 액션이 서로 독립적으로 운영되면서 코드가 훨씬 깔끔해졌고, 이런 구조 덕분에 향후 확장이나 리팩터링에도 유연하게 대응할 수 있을 것이라 생각했다. 복잡한 상태란 단순 값의 변화뿐 아니라 액션이 여러 상태에 서로 영향을 주고 상태 변화가 체계적으로 관리되어야 하는 경우라는 결론에 이르렀고, 앞으로는 단순한 상태는 useState로, 구조가 복합적이고 액션 및 로직 분리가 필요한 상황에서는 useReducer를 적극적으로 선택하는 습관을 들이려 한다.
물론 단점도 있었다. 개념에 대한 이해가 필요하다는 점에서 useState에 비해 동작 흐름을 이해하는 데 시간이 다소 걸렸고, 상태가 단순할 때는 오히려 작성해야 할 코드가 많아 비효율적일 수 있었다. 또한 useContext와 함께 사용할 경우 동일한 Context 내에 여러 상태가 있으면 일부 상태 변경에도 관련 없는 컴포넌트가 리렌더링되는 문제가 있어, 상태가 자주 바뀌는 값은 useContext에 두는 게 비효율적이라 생각했다.
상태 관리 라이브러리를 쓰는 이유를 다시 묻다
여러 컴포넌트가 공유하는 상태와 useContext로 인한 불필요한 리렌더링, 이 두 가지를 개선하려고 상태 관리 라이브러리를 도입해 차이를 확인해보기로 했다. 리렌더링만을 이유로 라이브러리를 들이면 번들 크기만 커질 수 있어 기본 Hook으로 해결하는 편이 합리적이지만, 이번에는 학습을 위해 도입했다. 써보니 원하는 상태만 선택적으로 구독할 수 있어 필요한 부분만 리렌더링됐고, 상태 로직을 별도 파일로 분리하니 컴포넌트는 UI에만 집중할 수 있었다. Provider로 감쌀 필요가 없다는 점도 편리했다.
지금까지는 습관적으로 상태 관리 라이브러리를 사용해왔다. 하지만 꼭 필요한 상황이 아니라면 useReducer와 useContext처럼 기본 Hook 조합만으로도 충분하다는 것을 깨달았고, 라이브러리를 도입한다면 그 이유를 다시 명확하게 생각해보아야 할 것이다. 초기 설계 단계에서는 react-hook-form을 도입하면 리렌더링이 적고 더 효율적일 거라 생각했는데, 막상 공부하고 나니 react-hook-form도 useContext를 사용하는 것 같다는 생각이 문득 들었고 찾아보니 실제로 그랬다. 그동안 라이브러리를 깊게 생각해보지도 않고 사용해왔다는 점에서 반성하게 되었다.
깊이와 넓이 사이에서 또 구현을 택하다
깊이 있는 학습과 얕고 넓은 학습 사이에서 많이 고민했다. 상태 관리는 직접 적용하며 차이를 느낄 수 있어 큰 도움이 됐지만, fetch API를 다룰 때는 더 공부하고 싶은 마음과 남은 작업 사이에서 갈등했다. 결국 학습은 주말로 미루고 구현을 우선했는데, 앞서 언급한 캠퍼분의 조언을 먼저 들었다면 학습을 택했을 것이다. 어떤 프로젝트에서든 중요한 데이터 패칭을 아직 완전히 이해하지 못했으면서 또다시 같은 선택을 반복했다는 점이 아쉽고 답답했다.
앞으로는 구현에 필요한 최소한의 이해가 아닌 개념을 확실히 익히는 학습을 중점으로 하려 한다. 특히 fetch API처럼 기본적이면서도 중요한 기술은 이번 부스트캠프 기간에 반드시 완전하게 이해하고 넘어갈 것이다. 이런 핵심 기술조차 구현을 위한 학습으로만 머무른다면 지난 시간들과 다를 바 없을 것이라 생각한다.
그래서 남은 시간 동안 데이터 통신 과정을 좀 더 깊이 있게 학습하려 한다. fetch가 어떤 방식으로 동작하고 요청과 응답이 어떤 흐름을 통해 데이터를 주고받는지 명확히 이해하고자 하며, 단순히 API를 호출하는 수준이 아니라 내부적으로 어떤 절차를 거쳐 브라우저에 데이터가 전달되는지를 구체적으로 살펴볼 계획이다.
정리하며
어느덧 멤버십 기간의 중간 지점이 다가오고 있다. 그동안 걸어온 길을 되돌아보며 과연 올바른 방향으로 나아가고 있는지 스스로에게 묻게 된다. 이번 주의 경험들은 내가 어떻게 성장하고 있는지, 그리고 앞으로 어떻게 성장해 나가야 할지 다시 한번 깊이 생각하게 만들었다. 이럴 때일수록 이전보다 더 집중해서 몰입하는 시간이 필요하다고 느끼며, 남은 기간에도 흔들림 없이 나아가며 성장을 확실히 체감할 수 있도록 더욱 최선을 다하고 싶다.
이번 주를 통해 한계를 분명히 느꼈다. 그래서 다음 주에는 할 수 있는 일과 아직 할 수 없는 일을 명확히 구분하려 한다. 전체 요구사항에 맞추어 무작정 계획을 세우기보다는 지금의 나에게 가능한 범위 내에서 최선의 결과를 내는 방향을 택할 것이다. 모든 것을 커버하려다 보면 결국 아무것도 깊게 남지 않는다는 것을 배웠고, 이제는 무엇을 할 수 있는가에 집중하며 그 안에서 확실히 성취할 수 있는 부분을 만들어가려 한다.
이번 미션에서는 로그인 기능을 구현하는 요구사항이 있었다. 이를 계기로 인증과 인가의 전체적인 흐름을 체계적으로 학습하고 머릿속에 전체 그림을 그려볼 계획이다. 세션, 토큰, OAuth, 쿠키 등 다양한 개념들이 등장했지만 단순히 각각을 따로 이해하는 데서 그치고 싶지 않다. 개념을 분리해서만 공부하다 보면 이들 사이의 관계와 흐름이 명확하게 연결되지 않는다는 점을 느꼈고, 전체 시스템 구조 안에서 각 개념이 어떤 역할을 담당하는지 정리하며 로그인 과정을 나만의 그림처럼 통합적으로 정리해보고자 한다.