- Published on
lv4 2주차 회고
- Authors
- Name
- Jiny
Intro
이번주는 총 3가지 키워드로 설명지을 수 있을거 같다.
- immer.js & useImmer
- 포수타
- 면접 준비 1주차
이 키워드를 중심으로 어떤 것을 했고 어떤 것을 느꼈는지 한번 작성해보려고 한다.
Immer.js & useImmer
팀 내에서 사용하는 hook 중 하나인 useTravelPlanDays와 useTravelogueDays가 있다.
이 hook의 경우 현재 여행기, 여행 계획을 등록 & 수정 & 변환 때 Day(크게 여행 날짜, 날짜 별 장소, 상세 정보(여행기는 이미지, 여행 계획은 to do))에 대한 책임을 담당하고 있다.
const onChangeContent = (
{
// ...
}: {
// ...
}
) => {
setTravelPlanDays((prevTravelPlansDays) => {
const newTravelPlans = [...prevTravelPlansDays]
const todo = newTravelPlans[dayIndex]?.places[placeIndex]?.todos?.find(
(todo) => todo.id === todoId
)
if (todo) {
todo.content = content.slice(
FORM_VALIDATIONS_MAP.title.minLength,
FORM_VALIDATIONS_MAP.title.maxLength
)
}
return newTravelPlans
})
}
한 핸들러(여행 계획의 to do를 검색하는 경우)를 예시로 들면 매 순간마다 복사해서 값을 추가해줘야한다.
// useTravelPlanDays
return {
onChangeTravelPlanDays,
onAddDay,
onDeleteDay,
onAddPlace,
onDeletePlace,
onChangeContent,
onAddPlaceTodo,
onDeletePlaceTodo,
};
};
// useTravelogueDays
return {
travelogueDays,
onChangeTravelogueDays,
onAddDay,
onDeleteDay,
onAddPlace,
onDeletePlace,
onChangePlaceDescription,
onChangeImageUrls,
onDeleteImageUrls,
};
하지만 useTravelPlanDays와 useTravelogueDays의 핸들러를 모두 합하면 16개의 핸들러다.
만약 여행 계획이나 여행기 등록 & 수정 & 변환에 대한 유지보수 작업을 할 때 핸들러가 많은 만큼 복사해서 그 값을 반환하는 로직을 제외하고 변경하는 로직에 대한 책임만 놔두고 싶었다.
하지만 리액트의 경우 객체나 배열과 같은 참조형 데이터 타입에 대해 얕은 비교를 통해 참조 값이 변경된 경우에만 변경된 값을 보여줄 수 있다.
그래서 다른 라이브러리 도입이 필요하다고 느꼈고, immer.js와 useImmer을 통해 리팩터링 해보고자 했다.
const onChangeContent = (
{
// ...
}: {
// ...
}
) => {
setTravelPlanDays((previousTravelPlanDays) => {
const todo = previousTravelPlanDays[dayIndex]?.places[placeIndex]?.todos?.find(
(todo) => todo.id === todoId
)
if (todo) {
todo.content = content.slice(
FORM_VALIDATIONS_MAP.title.minLength,
FORM_VALIDATIONS_MAP.title.maxLength
)
}
})
}
결과적으로 객체 복사에 대한 책임을 draft 객체에 위임함으로써 개발자는 로직을 update 하는데만 집중할 수 있다.
이렇게 결과론적인 부분만 알면 좋겠지만, immer를 제대로 알고 써야 문제가 생겼을 때 제대로 대응할 수 있을거라고 생각했다.
그래서 immer과 useImmer이 어떻게 동작하는지 이해하고 쓰는 것이 필요했다.
요약만 하면 immer은 다음과 같은 개념을 통해 동작하게 된다.
- useImmer는 setState 함수를 호출 할 때 immer.js의 produce를 래핑한 상태로 호출하여 불변성에 대한 책임을 produce 함수에 위임한다.
- produce는 카피 온 라이트를 기반으로 한 복사 메커니즘을 가지고 있다.
- 또한, 구조적 공유를 통해 깊은 복사가 되더라도 모든 프로퍼티를 복사하는 것이 아닌 특정 프로퍼티만 복사하는 메커니즘을 가지고 있다.
- produce 콜백함수 내에서 값을 변경(set)한 경우 Proxy의 target이 동작하여 별도의 로직을 수행하게 된다.
자세한 내용은 테크니컬 라이팅에 추가적으로 작성할 계획을 가지고 있다.
성능 미션 워크숍
우아한테크코스 코치님께서 성능 미션에 대한 최종 회고를 진행하기 위해 따로 워크숍을 열어주셨다.
프론트엔드 성능에 대한 여러 개념들을 정리하기 위한 도구로 콘셉 맵
이라는 개념을 소개해주셨다.
콘셉 맵은 개념들 간 관계를 시각적으로 구조화 하는 방법
으로 새로운 정보를 기존 지식 구조와 연결하는 과정을 더 효과적으로 하기 위한 도구로써 소개된다.
콘셉 맵은 크게 3가지로 구분지을 수 있었다.
- 개념
- 연결선(개념들 사이 관계를 연결하는 선)
- 연결어(개념들 사이 관계를 명확히 정의하고 설명)
핵심은 연결어다. 연결어를 통해 단순히 개념을 이해하는 것을 넘어 내가 어떤 것이 필요해서 이 개념을 필요로 하는지 명확히 파악하는 것을 돕는 역할을 수행한다.
이렇게 개념 - 개념을 연결해가며 복잡한 하나의 주제에 대한 개념들을 구조화하여 학습함으로써, 만약 성능 개선을 해야하는 상황이 온다면 어떤 것을 해야할지 쉽게 떠올릴 수 있도록 도와줄 수 있다.
이번엔 낙타, 텐텐과 함께 프론트엔드 성능
에 대해 개념들을 컨셉 맵을 구조화하는 연습을 진행했고 위 사진과 같은 이미지를 완성할 수 있었다. (워낙 개념들이 많다보니 확대해서 보는 것을 추천한다 ^^..)
이번 시간을 통해 가장 크게 얻었던 부분은 특정 개념이 왜 필요할까?
를 바로 떠올릴 수 있는 부분이었다.
예를 들어 React의 lazy를 바라본다면 바로 code spliting이 떠오르게 되고 code spliting이 필요한 이유 = 필요한 것만 요청하기 위해
, 필요한 것만 요청하는게 왜 필요할까? = 로딩 성능을 개선하기 위해
로 귀결지을 수 있는 계기가 되었다.
포수타
이번 주 금요일에 우아한테크코스의 리더(교장님?)이신 포비께서 전원 참석을 하는 포수타(포비와의 수다타임)을 개최해주셨다.
아마 lv4에 본격적으로 취업에 대해 고민하는 크루들이 많기 때문에 전원 참석을 권장하셨다고 생각했다.
가장 인상깊었던 부분은 해당 슬라이드였다.
어떤 경험과 학습을 하든 그 목적이 취업
이 되어버리면 목적 의식이 완전히 흐려지게 된다.
내가 어떤 개발을 할 때 행복한지, 무엇을 할 때 성취감을 느끼는지를 전혀 알지 못한 채 단지 돈
을 벌기 위한 개발자로써 남게 된다.
물론 돈을 많이 버는 것 역시 중요하지만 직업을 선택할 때 가장 중요한건 이 일을 할 때 내가 재미를 느끼는가?
다.
흥미와 재미를 느낄 때 내가 하고 있는 일을 사랑할 수 있고 사랑을 할 때 하고 있는 행위를 지속할 수 있다고 생각해 해당 질문에 큰 흥미를 가지게 되었다.
결론적으로 생각한다면 나는 좋은 개발자
가 되고 싶은 마음이 있다.
사람들 마다 좋은 개발자
에 대한 생각이 각각 다르겠지만 내가 생각하고있는 좋은 개발자
는 하고 있는 일을 편하게 할 수 있도록 도와줄 수 있는 역할이다.
내가 생각하는 편함
은 코드를 유지보수할 때 코드의 의도와 구조를 명확하게 이해할 수 있도록 개선해주는 것이다.
사용자가 사용하기 편한 서비스는 만드는 것은 당연하다고 생각해오고 있기 때문에, 스스로 더 노력하고 싶은 부분은 코드의 의도와 구조를 명확하게 이해
시키는 부분이다.
이를 더 잘하려면 다른 이들과 함께 협업을 하며 어떤 컨벤션을 지켰을 때, 어떤 구조로 작성했을 때 편함을 느끼는지 지속해서 이야기해보고 노력하는 시간이 필요하다고 느꼈다.
이런 경험과 학습을 만들어가기 위해 나는 전자보단 후자
를 택해 앞으로도 꾸준히 정진할 예정이다.
면접 준비 1주차
우아한 사혼의 구슬(개발자로써 방향성 찾기) 스터디에서 이제 우아한 사혼의 면접 스터디로 변경해서 진행을 하고 있다.
아무리 프로젝트와 미션에 집중해야한다해도 최소한의 취업 준비는 필요하다고 생각했고 다른 스터디원들도 공감했기 때문에 해당 스터디를 진행하게 되었다.
첫주차 주제는 아래와 같았다.
- JavaScript의 data type
- React의 state & props
- CSS
면접을 준비할 때 React의 경우 공식 문서를, JS는 코어 자바스크립트를, CSS는 mdn이나 다른 블로그들 글을 보며 준비를 했다.
학습을 다하면 다음과 같이 질문에 대한 답변을 github discussion에 올리는 형태로 하여 다른 이들이 면접 질문을 정리할 수 있도록 했다.
주제 범위를 크게 잡다보니 크루들의 질문과 답변이 서로 달랐고, 더 넓은 범위로 학습할 수 있는 점이 큰 장점이었다.
단순 키워드 정리만 했음에도 이렇게나 많은 질문들이 있었다. (심지어 완벽하게 정리하지 못했는데도 이정도 양이다..)
면접을 진행할 땐 인터뷰어와 인터뷰이를 관찰하는 옵저버
, 질문을 제공하는 역할인 인터뷰어
, 질문에 답변하는 인터뷰이
총 3개의 part로 나누어 면접을 진행했다.
옵저버는 크게 기술
, 말하기
, 습관
적인 측면들을 살펴보며 피드백을 제공하는 역할을 수행하게 된다.
6명이기 때문에 옵저버 3, 인터뷰어 2, 인터뷰이 1로 진행했다.
첫 면접 준비였기 때문에 정말 떨렸다.
글로 작성하는건 쉽지만 이를 잘 답변하는건 완전 다른 영역이라고 생각했기 때문이다.
크게 다음과 같은 질문을 받았다.
- 리액트에서 상태 관리가 무엇이며, 왜 상태 관리가 필요할까?
- 리액트의 상태 변화를 감지할 수 있는 방법
- props drilling
- 자바스크립트 데이터 타입의 필요성
- Symbol 타입
- 깊은 복사 방법
- display none visibility hidden 차이
- px, rem, em의 차이점
1번의 질문을 제외하면 나머지 질문은 비교적 수월하게 답했지만 첫번째 질문을 답변하지 못한 부분은 정말 아쉬웠다.(react에서 중요한 부분 중 하나라고 생각해왔기 때문)
지금 만약 대답한다면 아래와 같이 답변할 거 같다.
리액트에서 상태 관리는 어떤 위치에서 데이터를 관리하기 위한 메커니즘이라고 생각합니다. 이 개념이 필요한 이유는 어떠한 상황이라도 개발자가 의도한 데이터가 서비스 내에 표현되어야 하기 때문입니다. 예로 들면 특정 데이터를 장바구니 item들이 공유받아야하는 경우 state를 부모 컴포넌트로 끌어올려 데이터를 공유 해야하는 경우도, context api를 통해 컴포넌트 depth가 깊은 컴포넌트들끼리 데이터를 공유해야하는 상황에도 항상 의도한 데이터를 사용자에게 일관성있게 보여줄 수 있어야한다고 생각했기 때문입니다.
이 답변을 생각하는데도 시간이 좀 걸린 것을 봐서 아직 상태 관리에 대해 부족함을 있음을 알게 되었다.
그 외 이런 피드백들을 추가적으로 받았다.
- 두괄식으로 말하면 더 깔끔할거 같아요.
- 교과서적인 답변도 좋지만, 자신의 경험에서 나오는 답변을 해도 좋지 않을까 싶어요.
- 눈을 면접관과 마주치는 연습이 필요할거 같고 가끔 눈을 감는 버릇이 있어요.
이제
라는 표현이 많은거 같다.- 긴장하는 모습이 눈에 띄게 보인다.
피드백을 돌아보며 아직 면접이 익숙하지 않아서 심리적으로 경직되고, 말이 불필요하게 많아지는 경향이 있다고 생각했다.
다음 면접 부턴, 긴장하지 않는 연습(인데놀이라도 사먹어야하나..)과 두괄식으로 답변을 시작하는 것을 면접 전에 의식적으로 액션 플랜을 세워 시도해 볼 예정이다.
스터디를 함께하는 크루들이 인터뷰어, 옵저버의 역할을 충실하게 수행해서 그런지 더 동기부여가 되었다.
내가 무언가를 더 잘해내려고 하는거보단 워낙 크루들이 잘하기 때문에 크루들과 최대한 씽크를 맞출 수 있도록 앞으로의 면접을 준비할 계획이다!
이런 스터디원들과 함께할 수 있어서 영광이었던 첫 주였다.
Outro
lv4도 벌써 1달을 지나오고 있다.
많은 것들을 해서 그럴까 가끔 교통 정리가 안되는 부분들이 있었다.
현재 lv4에서 해야할 것들이 5가지(테크니컬 라이팅, 팀 미션, 개인 미션, 팀 프로젝트, 면접 준비)다 보니 처음엔 하고 싶은 것들을 조금씩 진행했었다.
이렇게 하다보니 5가지 항목들에 대한 진행사항들을 모두 일일이 확인해야했어서 에너지 소모가 컸던거 같다.
그래서 그런지 스스로 지쳐갔던 부분들도 있었고 더 많은 것들을 할 수 있었을거 같은데, 하지 못했던 부분들이 있어서 개인적인 아쉬움도 있었다.
이런 부족한 부분들을 깨닫았기 때문에 다음주부턴 하나를 할 때 제대로 해야겠다고 느끼게 되어 이를 실천해보고자 한다.
집중력을 더 강화하기 위해 뽀모도로 타이머
사용에 대한 함께 자라기 스터디에 참여하게 되었다.
이 타이머를 잘 사용하기 위한 전문성을 강화하도록 도와주는 스터디인데 이 스터디에서 더 많은 것들을 배울 수 있는 한 주가 되었으면 좋겠다!