React 공식문서 이해하기 (27)

Syoee·2023년 12월 7일
0

React

목록 보기
27/30
post-thumbnail

Chapter 4. Escape Hatches

#5 반응형 Effect의 생명주기

학습 목차

1. Effect의 생명주기
2. Effect는 ‘반응형 값’에 반응한다.


1. Effect의 생명주기

  • 모든 React 컴포넌트는 동일한 생명주기를 거친다.
    • 컴포넌트는 화면에 추가될 때 마운트된다.
    • 컴포넌트는 새로운 props나 state를 받으면 업데이트됩니다. 이는 보통 상호작용에 대한 응답으로 발생한다.
    • 화면에서 제거되면 컴포넌트가 마운트 해제된다.
  • 컴포넌트에 대해 생각하는 좋은 방법이지만 Effect에 대해서는 생각하지 않는 것이 좋다.
  • 대신 각 Effect를 컴포넌트의 생명주기와 독립적으로 생각해보자.
    Effect는 외부 시스템을 현재 props 및 state에 동기화하는 방법을 설명한다.
    코드가 변경되면 이 동기화를 더 자주 또는 덜 자주 수행해야한다.
  • 직관적으로 React는 컴포넌트가 마운트될 때 동기화를 시작하고 컴포넌트가 마운트 해제될 때 동기화를 중지할 것이라고 생각할 수 있다.
    때로는 컴포넌트가 마운트된 상태에서 동기화를 여러 번 시작하고 중지해야 할 수도 있다.

KeyNote

  • 일부 Effect는 클린업 함수를 전혀 반환하지 않는다.
  • 대부분의 경우 함수를 반환하고 싶겠지만, 그렇지 않은 경우 React는 아무 작업도 하지 않는 빈 클린업 함수를 반환한 것처럼 동작한다.

1-1. 동기화가 두 번 이상 수행되어야 하는 이유

  • Effect의 본문은 동기화를 시작하는 방법을 지정하고, 클린업 함수는 동기화를 중지하는 방법을 지정합니다.
  • 예시 코드 참조

1-2. React가 Effect를 재동기화 하는 방법

  • 다른 컴포넌트에 다시 연결하려면 React가 Effect를 다시 동기화해야한다.
  • 예시 코드 참조

1-3. Effect의 관점에서 생각하기

  • 항상 한 번에 하나의 시작/중지 사이클에만 집중하자.
    컴포넌트를 마운트, 업데이트 또는 마운트 해제하는 것은 중요하지 않다.
    동기화를 시작하는 방법과 중지하는 방법만 설명하면 된다.
    이 작업을 잘 수행하면 필요한 횟수만큼 Effect를 시작하고 중지할 수 있는 탄력성을 확보할 수 있다.
  • JSX를 생성하는 렌더링 로직을 작성할 때 컴포넌트가 마운트되는지 업데이트되는지 생각하지 않는 것을 떠올리면 이해가 쉬울 것이다.
    화면에 무엇이 표시되어야 하는지 설명하면 나머지는 React가 알아서 처리한다.
  • 예시 코드 참조

1-4. React가 Effect의 재동기화 가능 여부를 확인하는 방법

  • 개발 모드에서 React는 즉시 강제로 동기화를 수행하여 Effect가 다시 동기화될 수 있는지 확인한다.
    도어락이 작동하는지 확인하기 위해 문을 열었다가 한 번 더 닫는 것과 비슷하다.
    React는 개발 중에 Effect를 한 번 더 시작하고 중지하여 클린업 함수를 잘 구현했는지 확인한다.
  • 예시 코드 참조

1-5. React가 Effect의 재동기화 필요성을 인식하는 방법

  • 컴포넌트가 다시 렌더링될 때마다 React는 사용자가 전달한 의존성 배열을 살펴보자.
    배열의 값 중 하나라도 이전 렌더링 중에 전달한 동일한 지점의 값과 다르면 React는 Effect를 다시 동기화한다.
  • 예시 코드 참조

1-6. 각각의 Effect는 별도의 동기화 프로세스를 나타낸다.

  • 일관된 로직을 별도의 Effect로 분리하면 코드가 “더 깔끔해” 보일 수 있지만 유지 관리가 더 어려워진다.
    따라서 코드가 더 깔끔해 보이는지 여부가 아니라 프로세스가 동일한지 또는 분리되어 있는지를 고려해야 한다.
  • 예시 코드 참조

2. Effect는 ‘반응형 값’에 반응한다.

  • 컴포넌트 내부에서 선언된 props, state 및 기타 값은 렌더링 중에 계산되고 React 데이터 흐름에 참여하기 때문에 반응형이다.
  • 예시 코드 참조

2-1. 빈 의존성을 가지고 있는 Effect의 의미

  • Effect의 관점에서 생각하면 마운트 및 마운트 해제에 대해 전혀 생각할 필요가 없다.
    중요한 것은 Effect가 동기화를 시작하고 중지하는 작업을 지정한 것이다.
  • 예시 코드 참조

2-2. 컴포넌트 본문에서 선언된 모든 변수는 반응형이다.

  • props와 state만 반응형 값인 것은 아니다.
    이들로부터 계산하는 값들 역시 반응형이다.
  • props나 state가 변경되면 컴포넌트가 다시 렌더링되고 그로부터 계산된 값도 변경된다.
    그렇기 때문에 Effect가 사용하는 컴포넌트 본문의 모든 변수는 Effect 의존성 목록에 있어야 한다.
  • 예시 코드 참조

2-3. React는 모든 반응형 값을 의존성으로 지정했는지 검토한다.

KeyNote

  • 어떤 경우에는 컴포넌트 내부에서 값이 선언되더라도 절대 변하지 않는다는 것을 React가 알고 있다.
    예를 들어, useState에서 반환된 설정자 함수useRef에서 반환된 ref 객체는 리렌더링 시 변경되지 않도록 보장되는 안정적인 값이다.
  • 안정적인 값은 반응하지 않으므로 린터를 사용하면 목록에서 생략할 수 있다.
    그러나 이러한 값을 포함하는 것은 허용된다. 변경되지 않으므로 상관없다.

2-4. 재동기화를 원치 않는 경우엔 어떻게 해야 하는가?

  • Effect는 반응형 코드 블록이다.
    내부에서 읽은 값이 변경되면 다시 동기화된다.
    상호작용당 한 번만 실행되는 이벤트 핸들러와 달리 Effect는 동기화가 필요할 때마다 실행된다.
  • 의존성을 “선택”할 수는 없다.
    의존성에는 Effect에서 읽은 모든 반응형 값이 포함되어야 한다.린터가 이를 강제한다.
    때때로 이로 인해 무한 루프와 같은 문제가 발생하거나 Effect가 너무 자주 다시 동기화될 수 있다.
    린터를 억제하여 이러한 문제를 해결하지 말자.
    대신 시도할 수 있는 방법은 다음과 같다.
    • Effect가 독립적인 동기화 프로세스를 나타내는지 확인하라.
      Effect가 아무것도 동기화하지 않는다면 불필요한 것일 수 있다.
      여러 개의 독립적인 것을 동기화하는 경우 분할하라.
    • ‘반응’하지 않고 Effect를 재동기화하지 않으면서 props나 state의 최신 값을 읽으려면, Effect를 반응하는 부분(Effect에 유지)과 반응하지 않는 부분(Effect Event라는 것으로 추출)으로 분리할 수 있다.
    • 객체와 함수를 의존성으로 사용하지 말자.
      렌더링 중에 오브젝트와 함수를 생성한 다음 Effect에서 읽으면 렌더링할 때마다 오브젝트와 함수가 달라진다.
      그러면 매번 Effect를 다시 동기화해야 한다.
  • 예시 코드 참조

! 주의 !

  • 린터는 의존성이 잘못되었을 때만 알 수 있다.
    각 사례를 해결하는 최선의 방법은 알지 못한다.
  • 만약 린터가 의존성을 제안하지만 이를 추가하면 루프가 발생한다고 해서 린터를 무시해야 한다는 의미는 아니다.
    해당 값이 반응적이지 않고 의존성이 될 필요가 없도록 Effect 내부(또는 외부)의 코드를 변경해야 한다는 뜻이다.

요약

  • 컴포넌트는 마운트, 업데이트, 마운트 해제할 수 있다.
  • 각 Effect는 주변 컴포넌트와 별도의 생명주기를 가진다.
  • 각 Effect는 시작중지 할 수 있는 별도의 동기화 프로세스를 설명한다.
  • Effect를 작성하고 읽을 때는 컴포넌트의 관점(마운트, 업데이트 또는 마운트 해제 방법)이 아니라 각 개별 Effect의 관점(동기화 시작 및 중지 방법)에서 생각해야한다.
  • 컴포넌트 본문 내부에 선언된 값은 “반응형”이다.
  • 반응형 값은 시간이 지남에 따라 변경될 수 있으므로 Effect를 다시 동기화해야한다.
  • 린터는 Effect 내부에서 사용된 모든 반응형 값이 의존성으로 지정되었는지 확인한다.
  • 린터에 의해 플래그가 지정된 모든 오류는 합법적인 오류입니다. 규칙을 위반하지 않도록 코드를 수정할 수 있는 방법은 항상 있다.

React 공식 문서

https://react.dev/

React 비공식 번역 문서

https://react-ko.dev/

MDN

https://developer.mozilla.org/ko/

Wikipedia

https://ko.wikipedia.org/wiki/

profile
함께 일하고 싶어지는 동료, 프론트엔드 개발자입니다.

0개의 댓글