노트

useEffectEvent

useEffectEvent

프런트엔드#react · 연결된 개념 3개

쉽게 말하면

useEffectEvent는 Effect 안에서 최신 값을 읽기만 하고, 그 값이 바뀌었다고 Effect를 다시 돌리지는 않게 하는 함수를 만들어요. 통화 중에 상대 연락처 메모가 바뀌었다고 전화를 끊고 다시 걸 필요는 없는 것처럼요.

비유가 깨지는 곳 의존성 경고를 숨기는 도구가 아니에요. url처럼 바뀌면 다시 연결해야 하는 값은 의존성에 그대로 두고, 최신 값을 읽기만 하는 부분만 빼야 해요. 렌더 중에 부르거나 자식에게 넘기면 안 돼요.

useEffectEvent는 Effect 안에서 부르되 의존성 배열(Dependency Array)에는 넣지 않는 이벤트 함수를 만드는 훅이다. 항상 최신 props·state를 읽지만, 그 값이 바뀐다고 Effect가 다시 실행되지는 않는다. React 19.2에서 정식이 됐다(2026 기준).

// 전: onConnect가 바뀔 때마다 연결을 끊었다 다시 맺는다
useEffect(() => {
  const conn = createConnection(url)
  conn.on('connected', () => onConnect(conn))
  conn.connect()
  return () => conn.disconnect()
}, [url, onConnect])
 
// 후: url이 바뀔 때만 재연결, onConnect는 항상 최신
const onConnected = useEffectEvent(onConnect)
useEffect(() => {
  const conn = createConnection(url)
  conn.on('connected', () => onConnected(conn))
  conn.connect()
  return () => conn.disconnect()
}, [url])
  • 핵심은 Effect 안의 로직을 둘로 나누는 것이다. 바뀌면 다시 동기화해야 하는 값은 의존성에 두고, 최신 값을 읽기만 하면 되는 부분만 Effect Event로 뺀다
  • 의존성 경고를 숨기는 용도로 쓰면 안 된다. 페이지 방문 로그를 pageUrl 없이 []로 돌리면 URL(Uniform Resource Locator)이 바뀌어도 로그가 안 남는다. 다시 실행돼야 할 값이면 의존성에 둔다
  • 제약
    • Effect 안이나 다른 Effect Event 안에서만 호출한다. 렌더 중에 부르거나 다른 컴포넌트·훅에 넘기지 않는다
    • 반환된 함수를 의존성 배열에 넣지 않는다
    • 이벤트 핸들러나 자식에게 넘길 콜백이 필요하면 일반 함수(또는 useCallback)를 쓴다

Effect를 아예 안 쓰는 방법이 먼저다(Effect가 필요 없는 경우). 배경은 부수 효과와 Effect.

출처: React - useEffectEvent

연결된 개념

이 노트를 가리키는 문서

뜻이 가까운 노트

  • useEffect와 useLayoutEffect

    useLayoutEffect는 useEffect와 같은 일을 하지만, 브라우저가 화면을 그리기(Paint) 전에 동기적으로 실행된다. useEffect는 그린 뒤에 실행된다.

  • 서버 렌더에서 훅이 하는 일

    서버 렌더(Server-Side Rendering, SSR)에서도 컴포넌트 함수는 실제로 호출되고, 그 안의 훅도 호출은 된다. 다만 서버에는 커밋(DOM 반영)이 없어서, 렌더 중 동기적으로 값을 계산하는 훅만 일하고 커밋 뒤에 도는 훅은 아무것도 하지 않는다. "이 훅은 클라이언트에서만 동작한다"는 말은 대개 "Effect 안의 일은 클라이언트에서만 일어난다"는 뜻이다.

  • React의 규칙과 렌더 순수성

    Rules of React는 React가 올바르게 동작하고 최적화하기 위해 코드가 지켜야 하는 규칙으로, 공식 문서가 세 가지로 정리한다. 핵심은 렌더가 순수한 계산이어야 한다는 것이다.

  • useSyncExternalStore

    useSyncExternalStore는 React 밖에 있는 상태(외부 스토어(External Store), 브라우저 API(Application Programming Interface))를 구독해 컴포넌트와 동기화하는 훅이다. 동시성 렌더링(Concurrent Rendering)에서도 모든 컴포넌트가 같은 스냅샷을 보게 보장해 tearing을 막는다(React 18+).

  • 이벤트 버블링·캡처링과 위임

    DOM 이벤트는 대상 요소에서만 끝나지 않고 트리를 따라 전파된다. 루트에서 대상까지 내려가는 캡처링(Capturing Phase), 대상에서 처리되는 타깃 단계(Target Phase), 대상에서 루트로 올라가는 버블링(Bubbling Phase) 순서다.

보기 옵션