[2024.06.03] TIL 32일차

김선민·2024년 6월 3일

# useEffect(setup, dependencies?)

  1. useEffect는 리액트 컴포넌트가 렌더링될 때마다 특정 작업을 수행하도록 할 수 있는 React Hook이다.

  2. 컴포넌트의 최상의 레벨에서 useEffect를 호출하여 Effect를 선언한다.
    import { useEffect } from 'react';

  3. setup 함수는 optional dependencies에 무엇이 오든 컴포넌트가 DOM에 마운트되면 일단 실행된다.
    setup 함수는 선택적으로 클린업 함수를 반환할 수도 있다.


# useEffect 주의사항

  1. useEffect는 훅이므로 컴포넌트 최상위 레벨 또는 자체 훅에서만 호출할 수 있다.
    반복문이나 조건문 내부에서는 호출할 수 없다. ( 필요한 경우 새 컴포넌트 추출 후 state를 그 안으로... )

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

  3. Strict 모드가 켜져 있으면 React는 첫 번째 실제 셋업 전에 개발 전용의 셋업 + 클린업 사이클을 한번 더 실행한다.
    이는 클린업 로직이 셋업 로직을 "미러링"하고 setup이 수행 중인 모든 작업을 중지하거나 취소하는지를 확인하는 스트레스 테스트이다. ( 문제가 발생하면 클린업 기능을 구현해야 한다. )

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


# useEffect 사용법

외부 시스템 연결하기

  • 컴포넌트가 페이지에 표시되는 동안 네트워크, 일부 브라우저 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]);
      // ...
    }

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

  • 해당 시스템에 연결하는 setup 코드가 포함된 셋업 함수,
    해당 시스템과 연결을 끊는 cleanup 코드가 포함된 클린업 함수를 반환해야 한다.
  • 해당 함수 내부에서 사용되는 컴포넌트의 모든 값을 포함한 의존성 목록.

2. React는 필요할 때마다 setup 및 cleanup 함수를 호출하는데,이는 여러 번 발생할 수 있다.

  • 컴포넌트가 페이지에 추가(마운트)될 때 마다 setup 코드를 실행한다.
  • 의존성이 변경된 컴포넌트를 다시 렌더링할 때마다
    • 먼저 이전 props와 state로 cleanup 코드를 실행
    • 그런 다음 새 props와 state로 setup 코드를 실행

3. 컴포넌트가 페이지에서 제거(마운트 해제)되면 마지막으로 한 번 cleanup 코드를 실행한다.


커스텀 훅으로 Effect 감싸기

  • Effect는 "탈출구"이다. 또는 더 나은 빌트인 솔루션이 없을 때 사용한다.

  • Effect를 수동으로 작성해야 하는 경우가 자주 발생한다면 이는 컴포넌트가 의존하는 일반적인
    동작에 대한 custom hook을 추출해야 한다는 신호일 수 있다.

  • 예를 들어, 이 useChatRoom 커스텀 훅은 Effect의 로직을 보다 선언적인 API 뒤에 숨긴다.
    그러면 모든 컴포넌트에서 이와 같이 사용할 수 있다.

    function useChatRoom({ serverUrl, roomId }) {
      useEffect(() => {
        const options = {
          serverUrl: serverUrl,
          roomId: roomId
        };
        const connection = createConnection(options);
        connection.connect();
        return () => connection.disconnect();
      }, [roomId, serverUrl]);
    }
    function ChatRoom({ roomId }) {
      const [serverUrl, setServerUrl] = useState('https://localhost:1234');

      useChatRoom({
        roomId: roomId,
        serverUrl: serverUrl
      });
      // ...
profile
웹 프론트엔드

0개의 댓글