반응형 effects의 생명주기

hyeon·2024년 11월 7일

1. 이펙트의 수명 주기

# React 컴포넌트의 수명 주기(마운트, 업데이트, 마운트 해제)

먼저 모든 React 구성 요소가 동일한 기본 수명 주기 단계를 공유한다는 점을 이해하는 것이 중요합니다.

  • 마운트: 구성요소가 처음으로 DOM에 추가됩니다.
  • 업데이트: 상태 또는 소품 변경으로 인해 구성요소가 업데이트됩니다.
  • 마운트 해제: 구성 요소가 DOM에서 제거됩니다.

그러나 effects의 수명주기는 컴포넌트의 생명주기와 독립적입니다. React에서 useEffect를 사용할 때 동작은 일반 컴포넌트 생명 주기와 약간 다릅니다. 이펙트의 생명주기는 단순히 마운트 및 마운트 해제에만 적용되는 것이 아니라, 동기화가 언제, 어떻게 시작하고 끝나는지를 나타냅니다.


2. React가 effect를 재동기화하는 방법

  • 마운트: useEffect에 종속성이 없는 경우(예: []) 구성 요소가 마운트될 때 한 번 실행됩니다.
  • 업데이트: 효과에 종속성이 있는 경우(예: [count]) 종속성 중 하나가 변경될 때마다(예: count가 변경될 때) 다시 실행됩니다.
  • 마운트 해제: 구성 요소가 DOM에서 제거되면 React는 마운트 해제하기 전에 useEffect에 정의된 cleanup 함수를 실행합니다.
import { useState, useEffect } from 'react';

function Example() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    console.log('Effect is running');
    // 진행 중

    return () => {
      console.log('Cleanup effect');
      // Cleanup 함수 실행
    };
  }, [count]); // count가 변경될때 마다 다시 실행

  return (
    <div>
      <h1>Count: {count}</h1>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

3. React가 effect의 재동기화 가능 여부를 결정하는 방법

React는 useEffect의 종속성 배열에 있는 종속성을 기반으로 효과를 다시 동기화해야 하는지 여부를 결정합니다.

  • 마지막 렌더링 이후 종속성 배열의 값이 변경된 경우 효과가 다시 실행됩니다.
  • 종속성이 제공되지 않으면 마운트 시 효과가 한 번만 실행됩니다.
  • 빈 종속성 배열 []이 전달되면 구성 요소를 마운트 해제했다가 다시 마운트하지 않는 한 React는 재동기화하지 않습니다.

4. 이펙트의 동기화 주기 확인 방법

console.log를 사용하여 효과가 실행되는 시기를 확인할 수 있습니다. React의 엄격 모드는 개발 중에 특정 수명 주기 메서드(예: useEffect)를 의도적으로 이중 호출하여 효과의 수명 주기와 관련된 문제를 감지하는 데 도움이 될 수 있습니다.

//main.jsx

const root = ReactDOM.createRoot(document.getElementById("root"));

root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);
useEffect(() => {
  console.log('Effect running');
}, [count]);

return (
  <div>
    <h1>{count}</h1>
  </div>
);
  • React의 Strict 모드는 개발 중에 Effect running을 두 번 기록하므로 재동기화 주기를 이해하는 데 유용합니다.

5. React가 이펙트를 재동기화해야 함을 인식하는 방법

React는 종속성 비교를 통해 효과를 다시 동기화해야 함을 인식합니다. React가 종속성의 변화를 감지하면 효과가 다시 실행되어야 한다는 것을 알게 됩니다. 이는 구성 요소가 렌더링된 후 다음 페인트 전에 발생합니다.

useEffect(() => {
  console.log('Effect runs due to count change');
}, [count]); // count가 변경될때 마다 다시 실행
  • React는 'count'를 추적하고 변경되면 효과가 다시 동기화되어 다시 실행됩니다.

6. 각 이펙트는 별도의 동기화 프로세스를 나타냅니다

각 useEffect는 별도의 동기화 프로세스입니다. 구성 요소에 여러 개의 'useEffect' 후크가 있더라도 React는 해당 후크를 자체 종속성에 따라 독립적으로 처리합니다.

useEffect(() => {
  console.log('Effect for count');
}, [count]);

useEffect(() => {
  console.log('Effect for name');
}, [name]);

-count 효과는 name 효과와 독립적으로 실행됩니다. 이는 별도의 동기화 프로세스입니다. 즉, count를 변경해도 name에 대한 효과가 트리거되지 않으며 그 반대의 경우도 마찬가지입니다.


7. 이펙트는 반응 값에 반응합니다

  • 반응형 값은 변경 시 구성요소가 다시 렌더링되도록 하는 변수입니다. 이는 상태 값, props 또는 컨텍스트 값일 수 있습니다.
  • 응답 값이 변경되면 React는 효과를 다시 동기화합니다.
    효과가 특정 값에 "반응"하도록 하려면 해당 값을 종속성 배열에 포함하세요.
useEffect(() => {
  console.log('Effect for responsive value');
}, [count]);
  • count는 반응 값이며, 이펙트는 count의 변화에 반응합니다.

8. 컴포넌트 본문에 선언된 모든 변수는 반응형입니다

React에서는 모든 state와 props가 반응형입니다. 즉, 시간이 지남에 따라 변경되어 구성 요소가 다시 렌더링될 수 있음을 의미합니다. 구성 요소 본체 내부의 변수는 명시적으로 상태 또는 소품으로 표시되지 않는 한 직접적으로 반응하지 않습니다.

function ChatRoom({ roomId, selectedServerUrl }) { // roomId는 반응형입니다.
  const settings = useContext(SettingsContext); // settings는 반응형입니다.
  const serverUrl = selectedServerUrl ?? settings.defaultServerUrl; // serverUrl는 반응형입니다.
  useEffect(() => {
    const connection = createConnection(serverUrl, roomId); // effect는 roomId 와 serverUrl를 읽습니다.
    connection.connect();
    return () => {
      connection.disconnect();
    };
  }, [roomId, serverUrl]); // 따라서 둘 중 하나가 변경되면 다시 동기화해야 합니다!
}

serverUrl은 prop이나 state 변수가 아닙니다. 렌더링 중에 계산하는 일반 변수입니다.

하지만 렌더링 중에 계산되므로 재 렌더링으로 인해 변경될 수 있습니다. 이것이 바로 반응형인 이유입니다.


참고 자료: 리액트 공식문서

profile
당근🥕

0개의 댓글