월간 회고록 - 23.04

se-een·2023년 4월 30일
0
post-thumbnail

👍 Liked

방학동안 푹 쉬기

4월1일부터 4월10일까지 레벨 1 방학이었다. 정말 푹 쉬었다. 잠을 정말 많이 잔 거 같은데 하루는 몇 시간동안 잘 수 있나 궁금해져서 16시간동안 자다 깨다를 반복한 적도 있다. 😇

밤낮 바뀐 것은 덤. 생활 루틴을 강제할 수 있는 환경을 갖추는 것이 어렵다.

한 5일동안은 놀다가 그래도 좀 공부는 해야겠다 싶어 계획했던 것들을 끄적여봤는데 효율적이지는 못했다. 타입스크립트 정복은 언제쯤..

바닐라 JS에서 리렌더링

바닐라 JS는 React 라이브러리처럼 컴포넌트 상태값 변경에 따라 리렌더링을 자동으로 해주지 않기 때문에 일일히 직접 관리해줘야했다.

컴포넌트 본인을 리렌더링 하는 것은 간단하지만, 다른 컴포넌트를 리렌더링 해줘야하는 부분에서 고민이 많았다. 리렌더링 해줘야하는 컴포넌트를 import 해서 render 메서드를 실행시켜주는 방법이 가장 간단하지만, 컴포넌트간 의존관계를 만들어두면 추후에 컴포넌트 관계도가 복잡해질 것 같아 Observer 패턴 등을 활용하여 컴포넌트간 의존성 없이 리렌더링을 진행했다.

그러다가 custom element를 활용해보고 Observer 패턴 외에도 Proxy 패턴, custom event 등을 사용해보았는데 시간이 많지 않아서 일단 써보고 나중에 정리해야지 하고 넘어갔던 부분이 있었다.

각각의 패턴에 따라 어떤 구조가 나올 수 있을지 정리해보고 싶었는데 방학 기간동안 나름 정리는 해둔 상태라 '그래도 뭐 하나는 해뒀구나'라는 성취감은 있었다.

컴포넌트 기능의 책임은 어디까지

레벨 1 마지막 미션을 진행하다가 문득 '컴포넌트 기능의 책임은 어디까지라고 바라봐야할까' 라는 질문이 떠올랐다.

여태 미션을 진행하면서 컴포넌트 기능의 책임은 액션이라고 보았다. 예를 들어, 'A 컴포넌트를 클릭하면 B 컴포넌트를 한 바퀴 돌린다.' 라고 상황을 가정하면, A 컴포넌트의 기능 책임은 '클릭할 수 있다.' 까지로 생각한 것이다. 그래서 B 컴포넌트를 돌리기 위해 Observer 패턴, Proxy 패턴 등등을 적용한 것이었다.

그런데 A 컴포넌트의 기능 책임을 '클릭하면 B 컴포넌트를 한 바퀴 돌린다.'까지 하나의 흐름으로 생각해볼 수도 있지 않나.. 라고 문득 생각이 들었다.

이 부분에 대해서 리뷰어님과 얘기를 나눠봤었고, 이 역시 정답은 없다만 주어진 상황에 맞게 알잘딱깔센하게 적용하면 될 것 같다. 기존에 갇혀있던 생각의 틀을 깨고 환기할 수 있는 순간이었어서 기분이 짜릿했다.

React 두려움 극복하기

우테코 오기 이전에 자바스크립트 문법에 대한 깊은 지식도 없이 무작정 Vue, React와 같은 프레임워크, 라이브러리를 공부하다보니 이게 왜 되는지, 왜 안되는지 전혀 감을 잡을 수가 없었다.

또한 어디까지가 자바스크립트 문법인지, 프레임워크 또는 라이브러리의 문법인지 가늠도 안 되는 것은 덤.

강의에서 그냥 하라는 대로 따라치다보니 재미도 없었고 쉽게 까먹었다. 그래서 조금 공부했다가 질려서 그만두고 몇 주 뒤에 까먹어서 다시 복습했다가 또 질리고, 시간은 가는데 정작 발전이 없어서 React에 대한 두려움만 생겼었다.

레벨 2 온보딩 미션을 진행할 때 React를 처음 접하는 느낌이었지만 이전과는 느낌이 달랐다. '아 이렇게 쓰는거구나~' 하는 느낌이 왔다. 그리고 잘 읽히지 않았던 공식 문서도 잘 읽혔고 왜 사람들이 공식 문서 봐라. 하는지 이해할 수 있었다.

지금은 React란 거대한 블랙박스이지만 차츰차츰 정복해서 화이트박스로 이해하는 날이 올 때까지 열심히 달려봐야겠다. 🏃

황준일님의 웹 컴포넌트 방식 다시 이해하기

황준일님의 웹 컴포넌트 방식이 워낙 유명하기도 하고, 레벨 1 로또 미션 때 무턱대고 사용해본 적이 있다. 그 당시에는 자바스크립트 클래스 상속의 동작 방식도 정확하게 몰랐고, setState, prop 이런 것들이 왜 필요한지 잘 이해할 수 없었는데 React를 사용해보고 다시 보니 그 의미를 잘 이해할 수 있었다.

꼭 '황준일님의 방식이 정답이다!' 라고는 할 수 없겠지만, 개인적으로 의미를 잘 이해하지 못하고 넘어간 부분이 아쉬웠었는데 그 아쉬움을 메꿀 수 있었다. 😇

📚 Learned

React의 PureComponent와 shouldComponentUpdate

온보딩 미션을 진행하던 중, 이전에 React를 배울 때 'PureComponent를 쓰면 렌더링 최적화가 된다더라.' 라고 얼핏 듣고 썼던 기억이 문득 들었다.

안 그래도 페어와 리렌더링 최적화에 대해서 고민 중이었는데, 실험해볼겸 바로 적용해보았다. React.Component 대신 React.PureComponent로 선언한 컴포넌트는 쉽게 최적화가 되었다.

React가 어떤 마법을 부리는지 궁금해져서 공식문서를 공부해본 결과 PureComponent는 내부적으로 shouldComponentUpdate 메서드를 이용하여 현재 propstate를 다음 propstate와 얕은 비교를 진행하여 변경된 경우에만 리렌더링을 진행하는 것이었다.

공식문서에서 shouldComponentUpdate 메서드는 조건부 렌더링이 아닌 렌더링 최적화를 위해서만 사용할 것을 권장하는데, 처음에는 '왜 그래야하지? 🤔' 하면서 무시하고 미션에서 모달을 조건적으로 렌더링하는데 썼었다.

미션 step 2 때 React Hooks로 마이그레이션 하면서 이곳 저곳에 문제가 터져나왔고 모달 구현 방식 자체를 통채로 바꿔버리게 되었다. 하지말라는데는 이유가 있음을 다시 한 번 깨닫는다. 😇

React.useState의 setter가 비동기적으로 동작하는 이유

const [value, setValue] = useState(0);

// ...

setValue(1);
console.log(value); // 0

// ...

위 코드에서 setValuevalue의 값이 당연히 1이 될 것이라고 생각했는데, 그렇지 않았다. 결국 setter는 비동기적으로 동작을 하는데 (그렇다고 비동기 함수는 아니라고 한다.) 왜 그렇게 동작할 수 밖에 없는지 정리해보았다.

정규표현식 g 플래그의 lastIndex

페이먼츠 미션에서 정규표현식을 상수화 하던 중에 발생한 일이다. 상수 처리하기 전에는 문제 없었는데 상수 처리를 한 이후에 일정 주기로 정규표현식이 정상 동작하지 못하는(?) 오류를 겪었다.

도저히 무슨 문제인지 원인을 못 찾다가 페어와 이야기 하던 중 g 플래그의 lastIndex 라는 옵션이 있다는 것을 알게 되었다. 이는 문자열에서 일치하는 값을 찾게 된 시점의 위치를 가리키며, 다음 검증 시 해당 위치로부터 검색을 다시 수행하는 특징이 있다.

따라서 다음과 같은 결과가 나온다. 😬

const REG_EXP = /l/g;

console.log(/l/g.test('hello')); // true
console.log(/l/g.test('hello')); // true
console.log(/l/g.test('hello')); // true

console.log(REG_EXP.test('hello')); // true
console.log(REG_EXP.test('hello')); // true
console.log(REG_EXP.test('hello')); // false

그래서 일정 주기로 정규표현식이 정상 동작하지 못한다고 느꼈던 것이다. 위 문제는 g 플래그 옵션을 제거하거나, lastIndex를 검증 후 0으로 초기화하면 해결할 수 있다.

💦 Lacked

React

레벨 2로 넘어오면서 React 라이브러리를 사용해서 미션을 구현하고 있다만, 바닐라 JS 때보다 더 어렵게 느껴진다. 미션 난이도 자체도 조금 상승한 것 같지만 React를 잘 사용하지 못하는 것이 가장 큰 것 같다.

아직까지는 벽을 느끼는 정도의 문제를 겪진 않았지만, React Hook을 사용하면서 '얘는 상태 업데이트 시켜줘서 리렌더링 하는 애', '얘는 리얼 DOM에 접근할 수 있는 애' 이 정도 수준으로 이해하고 있으니, 여간 찝찝한게 아니다.

리액트 공식문서가 업데이트(?) 된 것 같다. 온보딩 미션 이전에도 우테코 LMS 레퍼런스에 있던 자료지만 기존의 공식문서를 고집하고 있다가 이 곳으로 넘어오니 신세계였다. 😲

일단 미션에 적용해보고, 이후에 왜 그런 것인지 알아보고, 필요하면 벨로그에 정리하는 과정을 거쳐볼 예정이다. 곧 React에 익숙해지길 바라며.. 꾸준히 노력해봐야겠다. 💪

타입스크립트 (+React 타입스크립트)

온라인 강의을 통해 타입스크립트의 기본적인 문법은 어느정도 익힌 것(?) 같다. '이펙티브 타입스크립트'는 난이도가 꽤 있어서 읽다가 중간에 '러닝 타입스크립트'로 돌렸다.

'러닝 타입스크립트' 책을 통해 타입스크립트 실력을 더 업그레이드 해볼 예정이다. 추가로 React 자체의 타입도 있다보니 가끔씩 타입 에러 때문에 막히는 느낌이 있다. 다행히도 크루 중에 타입스크립트 고수가 있어서 도움을 받을 수 있었다. 레벨 2가 가기전에 나도 누군가에게 도움을 줄 수 있는 크루가 될 수 있도록 노력해봐야겠다. 💪

배움에 우선순위를 두기

위에서도 언급한 내용이지만 React란 거대한 블랙박스를 사용하면서 내부적으로 어떤 원리에 의해 동작하고 있는지 알 수가 없으니 찝찝한 느낌이 있다. 물론 오픈소스라 코드를 받아볼 수 있어서 슬쩍 봤는데 지금 내 수준에서 학습할 내용은 아닌 것 같다.

가끔 '이게 왜 이렇게 되는거지?' 라는 의문의 흐름 속을 타고 가다가 시간을 너무 많이 소모해버려서 정작 중요한 내용을 놓치게 되는 경우가 있었다. '황준일님 웹 컴포넌트' 방식을 React를 사용하고 난 뒤 다시 이해할 수 있었던 것처럼 배움에는 때가 있다는 것을 느낀다.

따라서 지금은 React가 어떻게 돌아가고 있는지가 중요한 것이 아니라, 어떻게 잘 사용할 수 있을지가 중요하므로 배움의 우선순위를 잘 두는 것을 의식적으로 노력할 필요성이 있어보인다.

profile
woowacourse 5th FE

1개의 댓글

comment-user-thumbnail
2023년 5월 17일

세인 회고록 정말 보기좋게 잘 작성하시네요! 글 잘 보았습니다!

답글 달기