[BFE.dev] useEffect() 2

치만·2026년 1월 25일

BFE.dev react

목록 보기
20/28
post-thumbnail

useEffect() 2

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

function App() {
  const [show, setShow] = useState(true)
  return <div>
    {show && <Child unmount={() => setShow(false)} />}
  </div>;
}

function Child({ unmount }) {
  const isMounted = useIsMounted()
  useEffect(() => {
    console.log(isMounted)
    Promise.resolve(true).then(() => {
      console.log(isMounted)
    });
    unmount(); 
  }, []);

  return null;
};

function useIsMounted() {
  const isMounted = useRef(false);

  useEffect(() => {
    isMounted.current = true;
    return () => isMounted.current = false;
  }, []);

  return isMounted.current;
}

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

출력 결과

false
false

풀이 과정

1. 초기 렌더링

  • false 출력: useIsMounted()에서 반환한 isMounted의 값 false를 기억하고 출력합니다.

2. 상태 업데이트 후 재렌더링

  • 상태값 변화 : ChilduseEffect 안에서 unmount()가 호출되어 재렌더됩니다.

  • useIsMountedcleanup 함수가 실행되어 Ref의 값은 false가 됩니다.

  • false 출력: isMounted는 첫번째 렌더에서 결정되었던 지역 변수(클로저) false입니다.

    🤔 그럼 어떻게 해야 Ref값을 기억할까?

    return isMounted.current (현재 방식)
    이 방식은 useIsMounted가 실행되는 그 찰나의 을 찍어서 넘겨주는 방식입니다.

    이후 useEffect에서 ref.current를 어떻게 하든 Child가 이미 받아버린 false라는 값 자체는 절대로 변하지 않습니다. 그래서 두 번 다 false가 나옵니다.


    return isMounted (Ref 객체 반환 방식)
    이 방식은 값이 들어있는 주소를 통째로 넘겨주는 방식입니다.

    Promise.then이 실행될 때 isMounted.current를 확인하면 그 순간 안에 들어있는 최신 상태값를 보게 됩니다.

profile
🌱개발 기록장

0개의 댓글