React 공식문서 스터디

useEffect (2)

려낭 2024. 6. 5. 22:41

useEffect란?

 

React에서 사용하는 훅 중 하나로, 컴포넌트가 렌더링 될 때 특정 작업을 수행할 수 있게 도와준다.

컴포넌트가 화면에 나타날 때나 사라질 때, 또는 특정 값이 변할 때 어떤 동작을 하고 싶다면 useEffect를 사용하면 된다.


 

useEffect 

 

컴포넌트의 최상위 레벨에서 useEffect를 호출하여 Effect를 선언한다.

import { useEffect } from 'react';
import { createConnection } from './chat.js';

function ChatRoom({ roomId }) {
  const [serverUrl, setServerUrl] = useState('https://localhost:1234');

  useEffect(() => {
    const connection = createConnection(serverUrl, roomId);
    connection.connect();
    return () => {
      connection.disconnect();
    };
  }, [serverUrl, roomId]);
  // ...
}

 

 

매개변수

 

셋업 함수: 컴포넌트가 화면에 나타날 때 실행할 작업을 정의한 함수. 이 함수는 컴포넌트가 처음 렌더링될 때 실행된다.

 

클린업 함수: 컴포넌트가 화면에서 사라지거나 업데이트 되기 전에 정리 작업을 정의한 함수이다.

클린업 함수는 선택사항이며, 셋업 함수에서 반환될 수도 있다.

 

리액트는 컴포넌트가 DOM에 추가되면 셋업 함수를 실행한다. 의존성이 변경되어 다시 렌더링 할 때마다 리액트는 (클린업 함수가 있는 경우) 먼저 이전 값으로 클린업 함수를 실행한 다음, 새 값으로 셋업 함수를 실행한다. 컴포넌트가 DOM 에서 제거되면, 리액트는 마지막으로 클린업 함수를 실행한다.

 

동작방식

  • 마운트(Mount) : 컴포넌트가 처음 화면에 나타날 때
  • 언마운트(Unmount) : 컴포넌트가 화면에서 사라질 떄
  • 업데이트(Update) : 컴포넌트가 특정 값이 변해서 다시 렌더링 될 때

선택적 의존성

 

useEffect 에서 선택적 의존성은 useEffect 함수 내에서 참조된 모든 반응형 값(reactive values)를 의미한다.

반응형 값은 다음을 포함한다.

  • props : 부모 컴포넌트로부터 전달된 값
  • state : 컴포넌트의 상태 값
  • 컴포넌트 본문 내부에서 직접 선언한 변수와 함수

의존성 배열

 

의존성 배열은 useEffect의 두번째 인자가 전달되는 배열로, 배열 안에 있는 값들이 변경 될 때 마다 useEffect가 실행된다. 이 배열에는 반응형 값들을 넣어야 한다

 

린터

React 용으로 구성된 린터는 useEffect 내에서 사용된 모든 반응형 값이 의존성 배열에 잘 지정되었는지 확인해준다.

만약 누락되면 경고를 표시한다.

 

>>

의존성 배열에 값이 있을 때

  • 배열 안의 값들이 변경될 때만 useEffect 가 실행된다
  • React는 각 의존성에 대해 Object.js로 이전 값과 비교한다

의존성 배열이 빈 배열일 때 

  • 컴포넌트가 처음 마운트 될 때만 useEffect가 실행된다

의존성 배열을 지정하지 않을 때

  • 컴포넌트가 다시 렌더링 될 때마다 useEffect가 실행된다.

(요약)

  • useEffect 의 의존성 배열에는 setup 코드 내에서 참조된 모든 반응형 값을 지정해야한다.
  • 의존성 배열을 정확히 지정하면 불필요한 렌더링을 피할 수 있다.

 

 

반환값

 

useEffect는 undefined를 반환한다.

useEffect는 훅이므로 컴포넌트 최상위 레벨 또는 자체 훅에서만 호출할 수 있다. 

반복문이나 조건문 내부에서는 호출할 수 없다. 필요한 경우 새 컴포넌트를 추출하고 state를 그 안으로 옮기면 된다.

 

외부 시스템과 동기화하려는 목적이 아니라면 Effect가 필요하지 않을지도 모른다.

 

Strict모드는 개발환경에서 컴포넌트의 잠재적인 문제를 찾아내기 위해 일부 함수를 추가로 실행한다.

 

Strict 모드에서 useEffect의 동작

  • 개발전용 셋업+클린업 사이클 : Strict 모드에서는 실제 셋업 함수가 실행되기 전에 개발 전용으로 한번 더 셋업과 클린업을 실행한다. 이를 통해 클린업 로직이 셋업 로직을 제대로 취소하거나 정리할 수 있는지 확인한다.

>>목적

스트레스 테스트 : 이 추가 실행은 클린업 로직이 셋업 로직을 미러링 하고 있는지 확인하기 위한 스트레스 테스트이다. 셋업이 수행중인 모든 작업을 클린업에서 중지하거나 취소할 수 있는지 확인한다.

안전성 확보 : 이 테스트를 통해 메모리 누수나 부작용이 없는지 확인할 수 있다.

 

의존성 중 일부가 컴포넌트 내부에 정의된 객체 또는 함수인 경우 Effect가 필요 이상으로 자주 실행될 위험이 있다. 이 문제를 해결하려면 불필요한 객체 및 함수 의존성을 제거하면 된다.

 

Effect가 상호작용(예:클릭)으로 인한 것이 아니라면, 시각적인 작업(예:툴팁 위치 지정)을 하고 있고, 지연이 눈에 띄는 경우(예:깜빡임), useEffect를 useLayoutEffect로 대체해야 한다.

 

상호작용으로 인해 Effect가 발생한 경우에도, 브라우저는 Effect 내부의 state 업데이트를 처리하기 전에 화면을 다시 그릴 수 있다. 만약 브라우저가 화면을 다시 칠하지 못하도록 차단해야 하는 경우라면 useEffect를 useLayoutEffect로 바꿔야 한다.

 

Effects는 클라이언트에서만 실행된다. 서버 렌더링 중에는 실행되지 않는다.

 

 

사용법

 

외부 시스템에 연결하기

 

때로는 컴포넌트가 페이지에 표시되는 동안 네트워크, 일부 브라우저 API 또는 타사 라이브러리에 연결 상태를 유지해야 할 수도 있다. 이러한 시스템은 React에서 제어되지 않으므로 외부(external)라고 한다.

 

컴포넌트를 외부 시스템에 연결하려면 컴포넌트의 최상위 레벨에서 useEffect를 호출해라.

import { useEffect } from 'react';
import { createConnection } from './chat.js';

function ChatRoom({ roomId }) {
  const [serverUrl, setServerUrl] = useState('https://localhost:1234');

  useEffect(() => {
  	const connection = createConnection(serverUrl, roomId);
    connection.connect();
  	return () => {
      connection.disconnect();
  	};
  }, [serverUrl, roomId]);
  // ...
}

 

useEffect에는 두 개의 인자를 전달해야 한다.

 

1. 해당 시스템에 연결하는 셋업코드가 포함된 셋업 함수

  •  해당 시스템과의 연결을 끊는 클린업 코드가 포함된 클린업 함수를 반환해야 한다

2. 해당 함수 내부에서 사용되는 컴포넌트의 모든 값을 포함한 의존성 목록

 

리액트는 필요할 때 마다 셋업 및 클린업 함수를 호출하는데, 이는 여러번 발생할 수 있다.

  1. 컴포넌트가 페이지에 추가될 때 (마운트) 마다 셋업 코드를 실행한다.
  2. 의존성이 변경된 컴포넌트를 다시 렌더링 할 때 마다 
    • 먼저 이전 props와 state로 클린업 코드를 실행한다.
    • 그런 다음 새 props와 state로 셋업 코드를 실행한다
  3. 컴포넌트가 페이지에서 제거되면 (마운트 해제) 마지막으로 한 번 클린업 코드를 실행한다.

'React 공식문서 스터디' 카테고리의 다른 글

useLayoutEffect  (2) 2024.06.11
useEffect (3)  (0) 2024.06.10
useEffect  (0) 2024.06.04
useReducer/useContext/useRef 발표자료  (0) 2024.06.03
useRef (2)  (0) 2024.05.30