useState와 비동기

노성호·2021년 6월 11일
0

react

목록 보기
7/12

Console.log

하위 컴포넌트의 상태를 갖고 있는 상위 컴포넌트가 있다. 저번에도 포스팅 했던것 같다. 계속 구현하다보니 뭔가 이상한점이 발견되었다.

const [someState, setSomeState] = useState<State>({ ...초기값 });
function someHandler(state: State) {
	setSomeState(state);
}
return (
  <>
    <SomeComponent callback={someHandler} another={another}/>
  </>
)

와 같이 코드를 작성했다. 콜백으로 내려간 someHandler가 SomeComonent에서 상태를 잘 가져오고 있는지 보려고 콘솔을 찍었다.

function someHandler(state: State) {
  setSomeState(state);
  console.log(someState);
}

초기값이 찍혔다... 하지만 당황하지 않고 로그를 하나 더 찍었다.

function someHandler(state: State) {
  setSomeState(state);
  console.log(someState);
  console.log(state);
}

핸들러가 올려보낸 상태 로그를 보니 변경된 상태가 제대로 작동하고 있었다. 그래도 확실하게 해보려고 useEffect를 이용해서 콘솔을 찍어보았다.

useEffect(() => {
  console.log(someState);
}, [someState])

핸들러에서 로그를 볼때와 달리 상태가 제대로 변하고 있었다.

렌더링

리액트의 컴포넌트는 상태가 변하면 리렌더링된다.

  1. 상태의 메모리 주소 변경
  2. 리렌더
  3. 함수 호출
  4. 상태의 초기값 설정(useState의 초기값)
  5. useState
  6. useEffect
  7. 새 상태를 가진 컴포넌트로 렌더링

대충 요런 과정을 거쳐서 렌더링 된다고 한다. 정확한 과정은 아닐수 있다. 직접 도큐먼트를 찾거나 한게 아니고 다른 개발자에게 들은 과정이다. 정확한 과정은 빠른시간내에 찾아보겠다.

일단 상태의 메모리 주소가 변경되면 리렌더링 과정이 일어난다. 함수(컴포넌트)가 호출되고, setState가 상태의 초기값을 설정한다. 그리고, 변한 상태의 setState가 호출되면서 상태를 변경한다. 이때 로그를 찍으면 초기값만 찍힌다.

State

컴포넌트는 상태를 여러개 가질 수 있다. 상태가 하나 변할때마다 리렌더링이 된다면 상태를 100개 가진 컴포넌트는 100번에 걸쳐 리렌더링 하게된다. 뭔가 비효율적이다. 그래서 리액트의 useState는 비동기로 처리한다고 한다. 상태가 변하면 변한 상태를 일단 콜스택? 큐?에 쌓아두고(순서대로 상태처리를 해야하기 때문에 큐가 되어야 할 것 같다) 나중에 한번에 처리한다.

그래서 setSomeState를 실행하고 난 후에 콘솔을 찍어도 상태가 제대로 변하지 않은 것 처럼 보였고, 그것 때문에 나는 한시간을 날렸지...

망할 리액트

0개의 댓글