React의 State는 대체 어디에서 관리되고 있는가에 대하여...

Jung Wish·2026년 3월 2일

React

목록 보기
2/2

확실히 포스트 트래픽은 AI쪽과 새로운 기술 써본 후기 이런쪽이 높기는 한데, 솔직히 아직까지 뭔가 포스팅 할만한 성과나 workflow는 없어서 오늘도 역시 주제에 대한 고민을 한시간 정도 했다.

요즘 AI 덕분에 공부가 쉬워졌기 때문에 이를 활용해서, 예전 면접에서 질문 받았었는데 제대로 답변을 못한거 같았는데 그때 당시에도 제대로 복기를 안했어서 공부할 겸 오늘은 Codex와 함께 React 톺아보기를 해보았다.

면접 회상

면접 질문 : React의 함수형 컴포넌트는 함수입니다. 또한 useState의 hook도 함수입니다. 그러면 해당 선언/사용하는 해당 state는 대체 어디에 저장되는 걸까요? 함수는 매번 호출 당시에 내부 값이 바뀔텐데 어떻게 기존 state를 유지하게 되는걸까요?

(대략 이랬던 것으로 기억한다. 클로저 개념에 대해 이야기 하다가 갑자기 나온 이야기 같기도하고 1년 반 정도가 지나서 희미해진 기억을 되돌아봤다. 현재 회사에서 나온 질문은 아니었고 최종까지 갔던 회사였다.)

당시 답변: 제가 정확히 코드를 뜯어보거나 분석해보진 않아서 정확하지 않아 추측해보자면, 결국은 useState는 React의 엔진 객체의 내부 메소드 일거고, 전역 외부 store가 존재하고 hook을 사용할때의 고유 값을 통해 key:value로 저장되고 있을 것 같습니다.

몇 점짜리 대답일거 같은가? 개인적으로는 한 40점 정도(ㅋㅋ)
1. 일단 자신감이 매우 없게 대답했다. (틀릴 수도 있지 뭘의 마인드 장착 필요)
2. 꼬리질문을 통한 고유 값 설정 기준 및 로직 추측에는 대답하지 못했다.

사실, 저 엔진을 뜯어보거나 관심이 있지 않을한은 저 구조까지 알고있는 사람은 많지 않을 것이고. 저 회사는 나중에 들어보니 리액트 코드 리딩 스터디를 하고 계시다고 한다. 질문의 요지는 아마도 아래와 같지 않을까. 대답이 갱장히 미흡했지만 기술면접은 감사하게 붙여주셨던것으로 봐서는 그냥 추론해내서 대답하려고 애쓰는 모습을 좋게봐주셨던 것 같다.

(1) useState는 어떤 원리로 동작하는 것인지 의문을 가져본적이 있는가?
(2) JavaScript가 돌아가는 원리를 기반으로 React는 어떻게 구현해냈을지 추측해낼 수 있는가?
(3) Class Component는 내부 method와 variable을 통해 변수를 제어할 수 있다 쳐도 Functional Component는 대체 어떻게 이 내용을 변환해서 사용할 수 있게 되었는지 설계 관점의 시야를 가졌는가?

AI 분석편

AI한테 질문을 똑같이 던져보니 아래와 같이 대답했다. (Codex-5.3)

함수형 컴포넌트의 state는 컴포넌트 함수 안에 저장되지 않습니다.
React가 내부적으로 관리하는 Fiber 노드의 Hook 저장소에 저장됩니다.

핵심 흐름은 다음과 같습니다.

  1. 컴포넌트가 렌더될 때 React가 컴포넌트 함수를 다시 호출합니다.
  2. useState를 만나면 React는 “현재 렌더 중인 Fiber의 n번째 Hook 슬롯”을 읽습니다.
  3. setState를 호출하면 값을 즉시 바꾸는 게 아니라, 그 Hook의 업데이트 큐에 action을 넣습니다.
  4. 다음 렌더에서 큐를 적용해 새 state를 계산하고, 다시 같은 Hook 슬롯에 저장합니다.

그래서 함수는 매번 새로 실행돼도 state가 유지됩니다.
유지의 주체가 함수 로컬 변수가 아니라 Fiber에 연결된 Hook 상태이기 때문입니다.

그래서 Fiber가 뭔데요.. 뭘 가지고 있는데요?

Fiber는 컴포넌트의 실행 결과와 상태, 그리고 다음 렌더 작업 정보를 담는 React의 작업 단위입니다.

React는 Fiber 트리를 순회하면서 어떤 컴포넌트를 다시 렌더할지, 어떤 state 업데이트를 처리할지, 어떤 DOM 변경을 커밋할지 결정합니다.

📌 Fiber는 다음과 같은 값을 담고 있습니다.
1. 현재 state 값 (memoizedState)
2. 상태 업데이트 큐 (queue)
3. 다음 Hook를 가리키는 링크 (Hook 체인 연결용)

리액트 rules-of-hooks에
"React relies on the order in which hooks are called ..."라고 언급하며 조건문, 반복문, 비동기 실행문과 함께 hook 사용하는 것을 지양하라고 말하고 있습니다. 이 또한, Fiber가 컴포넌트 단위에 생성되고 해당 컴포넌트에서 선언된 hook들을 선언 순서별로 slot을 만들어 저장하기 때문입니다.

Fiber가 근데 어떤시점에 만들어지는거죠..?

Fiber는 컴포넌트를 정의할 때가 아니라, 렌더 트리에 실제로 올라갈 때 생성됩니다.
정확히는:
1. createRoot(...).render() 또는 hydrateRoot(..., ) 시작
2. React가 루트부터 엘리먼트 트리를 해석
3. 각 엘리먼트(컴포넌트 인스턴스/DOM 노드)에 대응하는 Fiber를 생성(또는 재사용)
4. 이후 업데이트 때는 기존 current Fiber를 바탕으로 workInProgress Fiber를 만들어 작업 후 교체

📌 즉, 최초 마운트 때 트리 전반의 Fiber가 생기고, 이후에는 업데이트마다 새로 전부 만드는 게 아니라 재사용/복제(alternate)하면서 갱신합니다.

setState(state + 1), setState((v) => v+1)은 왜 가끔보면 결과값이 다를까요?

const [state, setState] = useState(initialValue); 이렇게 선언하고 특정 이벤트 핸들러 함수를 선언한다고 치면 () => {setState(v+1)} 해당 함수는 클로저로 상위 컴포넌트의 state를 참조하게 됩니다. setState(state + 1) 일반적인 경우는 크게 문제가 되지 않습니다.

그런데 만약에, 같은 스코프에 여러번 setState가 다음과 같이 호출된다면 예상치 못한 결과를 초래할 수 있습니다. setState에 의한 state 변경은 즉시 적용이 아닙니다. 따라서 순차적인 호출시 state+1은 클로저로 참조한 기존 state값이 적용될 것이기 때문에 의도한 결과가 산출되지 않습니다.

그러나 set 함수 내부 인자를 함수로 건네주게 되면 실행 방식이 다릅니다.
함수형 방식은 결국 Fiber가 건네주는 현재 상태의 정확한 state 값을 전달 받아 실행됩니다. 그래서, 같은 실행 scope안에서 여러번 state update가 발생하는데 정확한 업데이트를 의도할때는 함수형 업데이트 방식을 사용해야합니다.

마무리

AI한테 꼬리질문 하다보면, 기존에 비해 확실히 학습할 수 있는 시간이 효율적이게 되었다. 참 좋은 세상이다... 앞으로 이런 특정 프레임워크를 학습할 필요 자체가 없는게 아닌가? 싶을때도 있는데.

AI 제어를 잘 하려면, 최적화 작업에 AI를 쓰려면, 디버깅 포인트를 정확히 요청하려면 = 결국은 AI를 잘 쓰려면, 기본 구조와 설계 방식을 공부하는게 좋다고 생각한다.

실제로 이제 현업에서 직접 코드를 작성하는 일은 거의 없지만.
요구사항에 대한 AI 설계를 1회 정도는 검수해야 할때도 있기도 하지만 AI 모델 자체를 효율적으로 이용하기 위해서는 어떻게 작업과 책임 단위를 쪼개고 할당할지 등의 엔지니어링 요소가 반드시 필요해진다.

따라서 React라는 거대 프레임워크 설계와 동작원리에 대해 익히는 것은 새로운 프로젝트와 문제 해결에 꽤나 도움이 될 것이라고 본다. 예상치 못한 곳에서 해결 아이디어를 찾을 수 있기 때문이다. 잘 짜여진 구조를 학습 or 따라하는 것만큼 빠른 시도는 없다.

profile
Frontend Developer, 올라운더가 되고싶은 잡부 개발자, ISTP, 겉촉속바 인간, 블로그 주제 찾아다니는 사람

0개의 댓글