번역 자료 / / 2025. 5. 26. 17:52

[react 번역] <Activity>

출처: https://react.dev/reference/react/Activity


개요

<Activity>는 UI의 일부를 숨기거나 보여줄 수 있게 해주는 React의 실험적(Experimental) 컴포넌트입니다. "숨김(hidden)" 상태에서는 해당 UI가 화면에 보이지 않으며, 이때 React는 이 부분의 Effect를 언마운트하지만, React/DOM state는 보존합니다. "보임(visible)" 상태로 전환하면, 보존된 state를 그대로 사용해 빠르게 다시 보여줄 수 있습니다.

⚠️ 이 API는 실험적이며, 정식(stable) 릴리즈에는 포함되어 있지 않습니다. 프로덕션에서는 사용하지 마세요.

import { unstable_Activity as Activity } from 'react';

<Activity mode={isVisible ? 'visible' : 'hidden'}>
  <Page />
</Activity>

Reference

<Activity>

UI의 일부를 <Activity>로 감싸면, 해당 부분의 가시성(visible/hidden) 상태를 관리할 수 있습니다.

Props

  • children: 렌더링할 실제 UI.
  • mode (optional): "visible" 또는 "hidden". 기본값은 "visible"입니다. "hidden"일 때는 children이 화면에 보이지 않고, Effect가 생성되지 않습니다. "visible"에서 "hidden"으로 전환 시 Effect가 파괴(cleanup)되지만, state는 보존됩니다.

Caveats(주의사항)

  • "hidden" 상태에서는 children이 화면에 보이지 않습니다.
  • "visible"에서 "hidden"으로 전환 시, 모든 Effect가 언마운트(cleanup)되지만 React/DOM state는 파괴되지 않습니다. 즉, mount 시 1회만 실행되는 Effect는 다시 "visible"로 전환할 때 재실행됩니다.
  • 와 함께 사용하면, 예상치 못한 부작용을 미리 발견할 수 있습니다.
  • 과 함께 사용 시, hidden에서 visible로 전환하면 "enter" 애니메이션, visible에서 hidden으로 전환하면 "exit" 애니메이션이 동작합니다.
  • <Activity mode="hidden">로 감싼 부분은 SSR(서버사이드 렌더링) 결과에 포함되지 않습니다.
  • <Activity mode="visible">로 감싼 부분은 다른 콘텐츠보다 낮은 우선순위로 하이드레이션됩니다.

사용법

UI 일부를 미리 프리렌더링하기

<Activity mode={tab === "posts" ? "visible" : "hidden"}>
  <PostsTab />
</Activity>
  • "hidden" 상태로 렌더링하면, 해당 children은 화면에 보이지 않지만 낮은 우선순위로 프리렌더링됩니다. 이후 "visible"로 전환하면, 이미 준비된 children이 빠르게 마운트됩니다. 탭 UI 등에서 다음에 보여줄 콘텐츠를 미리 준비할 때 유용합니다.

UI 일부의 state를 보존하기

<Activity mode={tab === "posts" ? "visible" : "hidden"}>
  <PostsTab />
</Activity>
  • "visible"에서 "hidden"으로 전환하면, children의 Effect는 언마운트되지만 React/DOM state는 보존됩니다. 다시 "visible"로 전환하면, 이전 state가 그대로 복원됩니다. 예를 들어, 입력 폼의 draft 내용, 스크롤 위치 등을 유지할 수 있습니다.

트러블슈팅

숨겨진 Activity에서 Effect가 동작하지 않음

  • <Activity>가 "hidden" 상태일 때는 모든 Effect가 언마운트됩니다. 이는 구독(subscription) 등 불필요한 작업을 줄이고, 예를 들어 비디오 재생을 일시정지(pause)하는 등의 cleanup이 정상적으로 동작하게 합니다. 다시 "visible"로 전환하면 Effect가 재실행됩니다.

예시: 비디오 플레이어

import { useState, useRef, useEffect, unstable_Activity as Activity } from 'react';

function VideoPlayer({ src }) {
  const ref = useRef(null);
  useEffect(() => {
    const videoRef = ref.current;
    videoRef.play();
    return () => {
      videoRef.pause();
    };
  }, []);
  return <video ref={ref} src={src} muted loop playsInline />;
}

export default function App() {
  const [video, setVideo] = useState(1);
  return (
    <>
      <button onClick={() => setVideo(1)}>Big Buck Bunny</button>
      <button onClick={() => setVideo(2)}>Elephants Dream</button>
      <Activity mode={video === 1 ? 'visible' : 'hidden'}>
        <VideoPlayer src="https://archive.org/download/BigBuckBunny_124/Content/big_buck_bunny_720p_surround.mp4" />
      </Activity>
      <Activity mode={video === 2 ? 'visible' : 'hidden'}>
        <VideoPlayer src="https://archive.org/download/ElephantsDream/ed_1024_512kb.mp4" />
      </Activity>
    </>
  );
}
  • 단순히 display: none으로 숨기면, 비디오가 백그라운드에서 계속 재생될 수 있습니다. Activity를 사용하면, 숨겨진 비디오의 Effect가 언마운트되어 재생이 멈춥니다.

SSR에서 hidden Activity가 렌더링되지 않음

  • <Activity mode="hidden">로 감싼 부분은 SSR 결과에 포함되지 않습니다. 서버에서 해당 콘텐츠가 필요하다면, useDeferredValue 등 다른 방법을 사용해야 합니다.

출처: https://react.dev/reference/react/Activity

반응형
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유