[BFE.dev] useEffect() timing 2

치만·2026년 1월 30일

BFE.dev react

목록 보기
25/28
post-thumbnail

useEffect() timing 2

'infiniteLoopProtection:false'

import * as React from "react";
import { useState, useEffect} from "react";
import { createRoot } from "react-dom/client";

function App() {
  const [state] = useState(0)
  console.log(1)
  
  const start = Date.now()
  while (Date.now() - start < 50) {
    window.timestamp = Date.now()
  }
  
  useEffect(() => {
    console.log(2)
  }, [state])

  Promise.resolve().then(() => console.log(3))

  setTimeout(() => console.log(4), 0)

  return null
}

const root = createRoot(document.getElementById('root'));
root.render(<App/>)

출력 결과

1
3
4
2

풀이 과정

1. 초기 렌더링

  • 1 출력: root.render(<App />)가 실행되면서 1이 출력됩니다.

  • 3 출력: Promisesms 마이크로태스크(Microtask)로 분류되어 동기 코드(Call Stack)가 완전히 비워지고 실행됩니다.

  • 4 출력: setTimeout매크로태스크(Macrotask)로 분류되어 마이크로태스크 큐가 완전히 비워지고 실행됩니다.

  • 2 출력: useEffect는 브라우저가 화면 렌더링을 마친 시점에 실행됩니다.

    🕒 렌더링 순서

    1️⃣ 동기 (Sync): 자바스크립트 메인 스레드에서 즉시 실행합니다.

    2️⃣ Microtask: 호출 스택이 비워지자마자 실행되는 최우선으로 실행됩니다.

    3️⃣ Macrotask: setTimeout 등 일반적인 비동기 태스크로 microtask가 비워지면 실행됩니다.

    4️⃣ Effect: 브라우저가 화면을 그린 뒤 실행됩니다.


profile
🌱개발 기록장

0개의 댓글