[우테코] 레벨 5 - 2주차 회고

Sally·2022년 11월 13일
2
post-thumbnail

이번주는 혼돈의 연속이였다. 정말 맞는 표현일지도...?🤔

이번 주는 면접 발표와 리크루팅데이가 모두 있었던 한 주여서 더 정신이 없다고 생각했던 것 같다.

월요일날 오후 한 시까지 우아한형제들 지원서 제출이 끝난 후 바로 당일날 오후 3시 쯤 면접일정이 나오게 되었다. 당일날 나올 것이라고 생각까지 못했기 때문에 갑작스럽게 느껴지기도 했다.

제일 첫날 면접을 보는 사람들은 당장 이틀 후인 목요일날 면접을 보아야 했기 때문에 더 갑작스러웠을 것 같다.

그렇게 다들 이번 한 주는 면접준비를 열심히 하기 시작했다.

나와 같은 경우에도, 자바스크립트 , 리액트, 네트워크, 타스 등의 정리를 다시금 시작했다.
리액트는 지금 좀 알고 다시 보기 시작하니, 더 재밌게 읽을 수 있었다.
그러다가(?) useState구현부가 궁금해졌다.

useState는 클로저로 구현되었을까?

리액트의 공식문서를 다시금 읽으면서, useState에서 클로저를 사용하였을까 궁금했다.
나의 개인적인 의견으로는 리액트의 공식문서를 읽으면서 클로저가 계속해서 떠올랐다.

useState에서 클로저를 썼을 것 같다!

난, 개인적으로 useState를 보았을 때에 클로저를 사용했을 것이라고 생각했다. 이유는 2가지이다.

첫 번째로, useState에서 클로저를 사용하여서 state에 대해서 setState를 통해서만 접근이 가능하도록 보호해두었을 것 같다.
두 번째로, 클로저를 사용하여서 함수의 호출이 끝났어도 참조값이 남아있어서 리액트가 상태값들을 들고 있을 것 같다는 생각이였다.

아무리 구글링을 해도 답이 나오지 않아, 주변의 크루나 공원에게 여쭤보았고 공원이 이에 관해 힌트를 주었다!

공원이 주신 hook구현부의 코드를 뜯어본 블로그 글

해당 글을 차근 차근 읽어보니, useState를 구현하는데에서는 클로저를 사용하고 있긴했었다.
하지만, 이번에 React18에서 상태 업데이트를 이벤트 리스너에서만 호출된 것을 모아서하는 것에서 여러 상태 업데이트 로직을 한 번에 모아서 하는 것으로 바뀌였기 때문에 관련 구현부가 바뀌었을 수도 있었다.

그래서 태태와 함께 깃허브에 올라와 있는 리액트의 useState구현부 코드를 같이 살펴보았다.

*리액트 useState의 구현부를 완전히 파악한 것은 아니기 때문에 하나의 의견으로 봐주시면 좋을 것 같습니다!

hook은 객체로 이루어져 있더라

function mountWorkInProgressHook(): Hook {
  // hook 객체에 대해서는 업데이트 구현체에서 자세히 다룹니다.
  const hook: Hook = {
    memoizedState: null, // 컴포넌트에 적용된 마지막 상태 값
    queue: null, // 훅이 호출될 때마다 update를 연결 리스트로 queue에 집어넣습니다.
    next: null, // 다음 훅을 가리키는 포인터

    // 업데이트 구현체에서 설명
    baseState: null,
    baseUpdate: null,
  }

  if (workInProgressHook === null) {
    // 맨 처음 실행되는 훅인 경우 연결 리스트의 head로 잡아둠
    firstWorkInProgressHook = workInProgressHook = hook
  } else {
    // 두번 째부터는 연결 리스트에 추가
    workInProgressHook = workInProgressHook.next = hook
  }
  return workInProgressHook
}

*출처

(블로그에 기술되어 있던 글이지만, 현재 구현부와 코드가 같아 설명이 같이 기재되어 있어 이로 대체한다)

훅은 객채로 이루어져있고, next라는 프로퍼티를 통해서 훅과 훅 사이를 링크드 리스트로 연결하고 있었다.

그래서 훅을 생성할 때마다 링크 리스트에 차례대로 연결된다.

이 부분에서, 리액트가 함수형 컴포넌트 임에도 불구하고 훅을 호출 순서를 기억함으로써 상태를 관리할 수 있었다는 말이 이 구현부를 두고 말하는 것일까? 라는 생각도 들었다.
(너무 재밌어...!😎)

그 중, 우리는 mountState함수에 집중했다.

mountState를 보자 👀

function mountState<S>(
  initialState: (() => S) | S,
): [S, Dispatch<BasicStateAction<S>>] {
  const hook = mountWorkInProgressHook();
  if (typeof initialState === ‘function’) {
    // $FlowFixMe: Flow doesn’t like mixed types
    initialState = initialState();
  }
  hook.memoizedState = hook.baseState = initialState;
  const queue: UpdateQueue<S, BasicStateAction<S>> = {
    pending: null,
    lanes: NoLanes,
    dispatch: null,
    lastRenderedReducer: basicStateReducer,
    lastRenderedState: (initialState: any),
  };
  hook.queue = queue;
  const dispatch = (queue.dispatch = (dispatchSetState.bind(
    null,
    currentlyRenderingFiber,
    queue,
  ): any));
  return [hook.memoizedState, dispatch];
}

(리액트는 useState구현부를 숨겨놓았다! 그래서 해당 파일의 경로는
react-reconciler > src > ReactFiberHooks.new.js 이다)

우리가 집중해서 봐야할 것은 queue와 dispatch이다.

queue

queue를 보게 되면 앞서 살펴보았던 hook의 객체프로퍼티 중 하나이다.
그래서 해당 큐를 훅의 queue에 할당하고 있는 것을 볼 수 있다.

const queue: UpdateQueue<S, BasicStateAction<S>> = {
    pending: null,
    lanes: NoLanes,
    dispatch: null,
    lastRenderedReducer: basicStateReducer,
    lastRenderedState: (initialState: any),
  };
  hook.queue = queue;

dispatch

다시 dispatch를 보자
해당 부분을 보면, bind를 통해서 null을 this로 currentlyRenderingFiber와 queue를 인자로 넘겨 새로운 함수를 생성하였다. (여기서 내부 변수를 참조하고 있음을 알수있다)

const dispatch = (queue.dispatch = (dispatchSetState.bind(
    null,
    currentlyRenderingFiber,
    queue,
  ): any));

그리고!!! 해당 dispatch를 반환해준다!

return [hook.memoizedState, dispatch];

해당 return문은 배열구조할당으로 우리가 useState를 활용할때 선언할 때 보이는 그 모습이다.

const [state,setState] = useState('');

결국, 내부 변수인 queue를 참조하는 dispatch 함수를 반환하고 있기 때문에 클로저가 사용되긴 됐다!

뭔가 얼렁뚱땅 결론 이긴하지만, 태태와 함께 클로저가 사용되고 있는 구문을 보긴 하니깐 기분은 좋았다 😎
면접을 앞두고 구현부를 까보니깐 더 재밌더라

리쿠르팅 데이

금요일은 리쿠르팅 데이였다.
여러가지 회사가 평소 우리가 공부를 하던 루터회관에 와서 회사들이 와 있으니 신기하기도 하고 캠퍼스가 낯설게 느껴지기도 하였다.

최근 들어서 채용공고에 SSR을 우대사항으로 써놓은 곳이 많았다. 그래서 실제로 SSR을 많이들 사용하고 있는지 궁금하여서 채용 부스에가서 SSR정말 사용하는지 질문들을 하고 다녔다.

사용하고 있는 곳도 있고 아닌 곳도 있었다.
그래서 개인적으로는 신입이 SSR을 못 한다고 해서 초조함을 느낄 필요는 없다고 생각했다.

리쿠르팅 데이까지 지나고 보니 다들 마음이 싱숭생숭해진 것 같다.
올 한 해 우테코 4기 크루들 모두 열심히 몰입했던 것을 봤고 또 같이 해내갔기 때문에 다들 좋은 결과가 있었으면 좋겠다.

0개의 댓글