Skip to main content

fast-refresh

id: fast-refresh title: Fast Refresh

Fast Refresh는 리액트 네이티브의 기능으로, 리액트 컴포넌트를 변경할 때 거의 즉각적인 피드백을 제공한다. Fast Refresh는 기본적으로 활성화되어 있으며, 리액트 네이티브 개발자 메뉴에서 "Enable Fast Refresh" 옵션을 토글할 수 있다. Fast Refresh를 활성화하면 대부분의 수정 사항이 1~2초 내에 반영된다.

동작 원리

  • React 컴포넌트만 내보내는 모듈을 수정하면, Fast Refresh는 해당 모듈의 코드만 업데이트하고 컴포넌트를 리렌더링한다. 파일 내의 스타일, 렌더링 로직, 이벤트 핸들러, 또는 효과 등 모든 부분을 수정할 수 있다.

  • React 컴포넌트가 아닌 다른 것들을 내보내는 모듈을 수정하면, Fast Refresh는 해당 모듈과 이를 임포트하는 다른 모듈들도 함께 다시 실행한다. 예를 들어, Button.jsModal.js가 모두 Theme.js를 임포트하는 경우, Theme.js를 수정하면 두 컴포넌트 모두 업데이트된다.

  • 마지막으로, React 트리 외부의 모듈에서 임포트하는 파일을 수정하면, Fast Refresh는 전체 페이지를 새로고침하는 방식으로 동작한다. React 컴포넌트를 렌더링하는 동시에 React가 아닌 컴포넌트에서 임포트하는 값을 내보내는 파일이 있을 수 있다. 예를 들어, 컴포넌트가 상수를 내보내고, React가 아닌 유틸리티 모듈이 이를 임포트하는 경우가 있다. 이때는 상수를 별도의 파일로 분리하고 두 파일에서 모두 임포트하는 방식을 고려할 수 있다. 이렇게 하면 Fast Refresh가 다시 동작할 수 있다. 다른 경우도 보통 비슷한 방식으로 해결할 수 있다.

오류 복구 기능

Fast Refresh 세션 중 문법 오류가 발생하면, 오류를 수정하고 파일을 다시 저장하면 된다. 이때 빨간색 오류 창이 사라진다. 문법 오류가 있는 모듈은 실행되지 않기 때문에 앱을 다시 로드할 필요가 없다.

모듈 초기화 과정에서 런타임 오류가 발생한 경우(예: StyleSheet.create 대신 Style.create를 입력한 경우), 오류를 수정하면 Fast Refresh 세션이 계속 진행된다. 빨간색 오류 창이 사라지고 모듈이 업데이트된다.

컴포넌트 내부에서 런타임 오류가 발생한 경우에도, 오류를 수정하면 Fast Refresh 세션이 계속된다. 이때 React는 업데이트된 코드를 사용해 애플리케이션을 다시 마운트한다.

앱에 에러 바운더리가 있다면(프로덕션 환경에서 우아한 실패 처리를 위해 권장), 다음 편집 시 빨간색 오류 창 이후에 렌더링을 다시 시도한다. 이는 에러 바운더리가 루트 앱 화면으로 강제 이동하는 것을 방지해 준다는 의미다. 하지만 에러 바운더리를 지나치게 세분화해서는 안 된다. React는 프로덕션 환경에서 에러 바운더리를 사용하며, 항상 의도적으로 설계해야 한다.

제한 사항

Fast Refresh는 편집 중인 컴포넌트의 로컬 React 상태를 유지하려고 시도하지만, 안전한 경우에만 가능하다. 파일을 편집할 때마다 로컬 상태가 초기화되는 몇 가지 이유를 살펴보자:

  • 클래스 컴포넌트의 로컬 상태는 유지되지 않는다. (함수 컴포넌트와 Hooks만 상태를 유지한다.)
  • 편집 중인 모듈이 React 컴포넌트 외에 다른 것을 내보낼 수 있다.
  • 가끔 모듈이 createNavigationContainer(MyScreen)과 같은 고차 컴포넌트 호출 결과를 내보낼 수 있다. 반환된 컴포넌트가 클래스라면 상태가 초기화된다.

장기적으로 볼 때, 코드베이스가 점점 더 함수 컴포넌트와 Hooks로 전환되면 상태가 더 많은 경우에 유지될 것으로 기대할 수 있다.

  • Fast Refresh는 기본적으로 함수 컴포넌트(와 Hooks)의 React 로컬 상태를 유지한다.
  • 때로는 상태를 강제로 초기화하고 컴포넌트를 다시 마운트하고 싶을 수 있다. 예를 들어, 마운트 시에만 발생하는 애니메이션을 조정할 때 유용할 수 있다. 이 경우, 편집 중인 파일 어디든 // @refresh reset을 추가하면 된다. 이 지시문은 파일 내에서만 유효하며, Fast Refresh가 해당 파일에 정의된 컴포넌트를 매번 편집할 때마다 다시 마운트하도록 지시한다.

Fast Refresh와 훅

가능한 경우 Fast Refresh는 컴포넌트의 상태를 편집 중에도 유지하려고 한다. 특히 useStateuseRef는 인자나 훅 호출 순서를 변경하지 않는 한 이전 값을 그대로 유지한다.

useEffect, useMemo, useCallback과 같이 의존성을 가진 훅은 Fast Refresh 중에 항상 업데이트된다. Fast Refresh가 진행되는 동안 의존성 목록은 무시된다.

예를 들어, useMemo(() => x * 2, [x])useMemo(() => x * 10, [x])로 편집하면 x(의존성)가 변경되지 않았더라도 다시 실행된다. React가 이렇게 동작하지 않았다면 편집 내용이 화면에 반영되지 않을 것이다.

이로 인해 예상치 못한 결과가 발생할 수도 있다. 예를 들어, 의존성 배열이 비어 있는 useEffect도 Fast Refresh 중에 한 번은 다시 실행된다. 하지만 Fast Refresh가 없더라도 useEffect가 가끔 다시 실행되는 상황에 대비해 코드를 작성하는 것은 좋은 습관이다. 이렇게 하면 나중에 새로운 의존성을 추가하기가 더 쉬워진다.