React <Activity> 의 래더링에 대해서

robin Han·2025년 10월 31일

이번에 React 19.2 업데이트된 개념으로 여려가지중에서
Activity, useEffectEvent, Partial PreRender에 대해서 글을 작성 해보았습니다.
기존에 알고 있었지만 개념이 애매모호했던 부분들과 아직 몰랐던 개념들에 대해서 혼자 질문을 해보면서 작성해보았습니다.

Activity

Activity는 React 19에서 도입된 개념으로 컴포넌트가 실제로 사용자에게 UI가 보여지고있는 상태 또는 백그라운드 상태인지를 인식하고 관리하기 위한 API입니다.

우선 기존에 UI를 사라지게 하기 위해 사용했던 방식으로

//React 조건부 렌더링 방식
{
	isShow && <div/> 
}
---
  // 브라우저 렌더링 방식 hidden 속성으로 처리 
	<div hidden={!isShow}/> 
--- 
  //css로 처리하는 방식 
		<div className={!isShow ? 'hidden' : ''}/> 

자 그럼 여기서 어떤 차이들이 있을까요?

React 렌더링 (Logical Rendering)

우선 React 렌더링의 조건은 해당 div가 React 렌더 트리에 포함되지않고 따라서 컴포넌트 메모리 또는 내부에 있느 모든 상태(state), useEffect, ref가 초기화가 됩니다, isShow가 true로 바뀌면 다시 처음부터 마운트를 진행합니다. 이렇게되면 보여지지않는 컴포넌트에 대해서 불필요한 메모리 또는 이벤트 리스너를 모두 정리할수있기 때문에 효율적으로 작동하고 리렌더링 부담이 적지만 매번 초기화하기때문에 내부에 있는 모든 상태값들이 유지 되지 않습니다.

브라우저 렌더링 (Physical Rendering)

브라우저 랜더링 방식은 해당 div가 항상 React 렌더트리에 존재하지만 브라우저에서 렌더가 아닌 display : none 으로 되어 내부에서 작동하는 상태 또는 이벤트리스너들이 계속 작동하고 유지됩니다. 이러한 값들을 유지하기위해서 메모리와 CPU를 계속 사용하기 때문에 성능이 떨어집니다.

그러면 hidden 속성과 css로 주는 display: none은 차이가 있을까 ?

우선 div가 hidden 속성을 사용할수있는 이유는 브라우저 기본 stylesheet에 정의 되어있는 스타일을 사용합니다.

[hidden] {
  display: none;
}

CSS로 주는 스타일과 큰 차이는 없지만 CSS우선 순위 문제로 css는 무시될수있고 display:none은 style object 비교로서 diff 비용이 더 들어가고 오버라이드 될수있는 가능성으로 의도적으로 숨기는 컴포넌트는 hidden 속성을 사용하면 보다 명시적으로 가독성 좋게 UI를 숨길수있습니다.

추가적으로 알아야하는 차이

우선 Logical Rendering인 React에서 메모리상의 컴포넌트 트리를 계산하고 diff를 비교하고 브라우저에 반영한다. 즉 무엇을 DOM에 반영할지 계산하는 과정으로 브라우저에게 명령할 내용을 준비하는 단계로 실제로 랜더링은 브라우저가 담당한다. React에서 Virtual DOM을 통한 업데으트를 실행하면 이를 브라우저가 랜더링 파이프라인으로 처리하여 Reflow -> Pain -> Composite 단계를 거쳐 랜더링을 진행합니다.


자 그럼 다시 React 19.2 Activity 업데이트로 돌아와서, Activity의 사용하는 이유는 컴포넌트를 언마운트하고 useEffect를 cleanUp하지만나중에 다시 사용할수있게 상태를 백그라운에서 저장하여 복원하수있는 장점이 있습니다.

Activity를 사용하는법은

<Activty mode={isShow ? 'visible': 'hidden'}>
  <childComponent/>
</Activity>

mode라는 props를 통해서 childComponent를 보여줄지 조건을 주어 UI를 숨길수있습니다. 이렇게 childComponent를 Activity로 감싸면 childComponent 내부에서 사용했던 상태값 저장하고 있을 수 있습니다. Activity에서의 hidden은 CSS 속성인 display: none을 가지고 있습니다 하지만 브라우적 랜더링과 달리 useEffect와 ref등 구독이 clean up 되어 성능적으로 개선 되었고, 또한 'visible'로 바뀌어을때 다시 상태를 복원하고 effect와 구독을 재생성합니다.

6개의 댓글

comment-user-thumbnail
2025년 10월 31일

오 항상 css로 숨기는 방식을 사용했는데, Activity를 사용하면 이런 것도 할 수 있군요! 감사합니다.

답글 달기
comment-user-thumbnail
2025년 10월 31일

어떤 케이스에 사용하는 게 좋을지 고민해보고 한번 적용해봐야겠네요! 차이점이 잘 정리 되어있어서 Activity의 필요성에 대해 파악할 수 있었어요. 감사합니다!

답글 달기
comment-user-thumbnail
2025년 10월 31일

저도 주로사용하던 css 방식이었는데 activity 사용하면 더 효율적으로 사용할 수 있겠네요!! 감사합니다

답글 달기
comment-user-thumbnail
2025년 10월 31일

오 생각보다 잘 사용할 곳이 많을 것 같아요! 공유 감사합니다 ㅎㅎ

답글 달기
comment-user-thumbnail
2025년 11월 28일

이 기능이 이제 나오다니에 대한 개탄스러움도 있지만 여전히 리액트는 개발하고 있는 점이 고무적으로 느껴집니다.

답글 달기
comment-user-thumbnail
2025년 11월 29일

오.. 아직 react 19 팔로업을 못했는데, 흥미로운 게 추가되었군요! 좋은 정보 감사합니다!

답글 달기