개발 노트

React - 지역변수 및 렌더링 본문

React

React - 지역변수 및 렌더링

알 수 없는 사용자 2023. 2. 7. 09:08

지역변수와 useState

이 두 변수는 메모리에 존재하는 시간과 변수에 접근할 수 있는 범위의 차이가 존재한다.

지역 변수(local variable) : '블록' 내에서 선언된 변수

지역 변수는 변수가 선언된 블록{} 내에서만 유효하며, 블록이 종료되면 메모리에서 사라진다.

이러한 지역 변수는 메모리상의 스택(stack) 영역에 저장되며, 초기화하지 않으면 의미 없는 값(쓰레기값)으로 초기화된다.

예시로 함수의 매개변수 또한 함수 내에서 정의되는 지역 변수로 취급됩니다.

 

함수형 컴포넌트의 hook들은 return값을 반환하고 종료된다.
useEffect안에 지역변수를 사용하고 setState(세터)를 사용 후 setTimeout을 사용 하여 5초 이후 state와 지역 변수를 사용하게 된다면?
useEffect안의 것들이 return을 끝내기 전에는 종료된 것이 아니기 때문에 timeout의 콜백함수를 쓸때에 지역변수는 살아있고 State는 사용 할 수 없다.

useState 비동기 처리

useState는 비동기로 동작한다, 정확히는 setState가 비동기로 동작한다.

 

이유는?

하나의 페이지나 컴포넌트 내에도 수많은 상태값이 존재한다. 만약 이 상태 하나하나가 바뀔 때마다 화면을 리렌더링 한다면 문제가 생길수도 있다.
때문에 리액트는 성능의 향상을 위해서 setState를 연속 호출하면 배치 처리하여 한 번에 렌더링하도록 하였다. 아무리 많은 setState가 연속적으로 사용되었어도 배치(batch) 처리에 의해서 한 번의 렌더링으로 최신 상태를 유지하는 것이다.

 

batch?

여러개의 state 업데이트를 하나의 리렌더링으로 묶는 것을 의미한다.

react는 16ms 동안 변경된 상태 값들을 하나로 묶는다. (16ms 단위로 batch를 진행한다.)

 

useState in React module

이제 useState가 왜 비동기로 동작하는지 알았다. 하지만 뭔가 조금 아쉬워서 React의 코드를 뜯어보았다.

React의 useState 함수이다. 이 함수는 resolveDispatcher라는 함수가 반환하는 객체의 useState라는 메서드를 실행하여 반환되는 값을 리턴한다.

그럼 이제 resolveDispatcher를 살펴보자.

resolveDispatcher 함수는 다시 ReactCurrentDispathcer라는 객체의 current 속성을 반환한다.

 useState는 ReactCurrentDispatcher 객체의 useState 메서드를 실행시키는 것이다.
이때 주목할 점은 ReactCurrentDispatcher가 객체라는 점이다.

객체이기 때문에 동일한 key 값에 대하여 이전의 값을 계속해서 덮어쓴다. 결국에는 마지막 명령어만 수행되는 셈이다. 아래처럼.

출처 https://garve32.tistory.com/m/39

 

[React] useState의 비동기 처리와 함수형 업데이트

#1. setState는 비동기로 동작한다 아래와 같이 동작하는 코드를 보자. 하나는 숫자를 1씩 증가시키는 버튼이고, 하나는 숫자를 1씩 감소시키는 버튼이다. import React, { useState } from "react" function App() {

garve32.tistory.com

 

그럼 useState를 동기적으로 처리하려면?

첫 번째로는, useEffeect의 의존성 배열을 이용하는 것이다. -> 어제 우리가 했던 두개의 useEffect를 사용해서 위에서 아래 방향으로 동기적 처리를 하는 것을 의미하는 듯 하다. (의존성 배열로 넣으면 무한루프에 걸렸던 것 같기 때문에)
두 번째로는, setState의 인자로 함수를 집어넣는 것이다(함수형 업데이트).

 

이렇게 setState의 인자로 함수를 집어넣으면 동기적으로 동작하는 것을 확인할 수 있다.
( setState내 함수의 매개변수로 이전 상태가 들어온다. )

 

결론

  • useState는 비동기적으로 동작하는 훅
  • 비동기적으로 동작하는 이유는 성능 최적화를 위함
  • 리액트는 성능 최적화를 위해 setState를 batch 처리한다.
  • useState를 동기적으로 처리하기 위해서는 함수형 업데이트를 사용하거나 useEffect의 의존성 배열을 활용하면 된다.