Dev/React.js

[React18] 12. Effect의 생명주기 (useEffect)

YummYum 2023. 10. 5. 00:00

Effect의 생명주기

Effect는 컴포넌트와 다른 생명주기를 가집니다. 컴포넌트는 마운트, 업데이트 또는 마운트 해제할 수 있습니다. Effect는 동기화를 시작하고 나중에 동기화를 중지하는 두 가지 작업만 할 수 있습니다. 이 사이클은 시간이 지남에 따라 변하는 props와 state에 의존하는 Effect의 경우 여러 번 발생할 수 있습니다. 

 

** 일부 Effect는 클린업 함수를 전혀 반환하지 않습니다. 이럴 경우 React는 빈 cleanup 함수를 반환한 것처럼 동작합니다.

 

개발 모드에서 React는 즉시 강제로 동기화를 수행하여 Effect가 다시 동기화될 수 있는지 확인합니다. 이는 개발 중에 Effect를 한 번 더 시작하고 중지하여 클린업 함수를 잘 구현했는지 확인합니다.

 


React가 Effect를 다시 동기화될 수 있는지 확인하는 방법

의존성 배열에 값을 포함시킴으로써 값에 의존하고 있음을 React에게 알립니다. 배열의 값 중 하나라도 이전 렌더링 중에 전달한 값과 다르다면 React는 동기화를 중지하고 동기화를 다시 시작합니다.

 

** 같은 의존성을 가져서 코드를 같이 Effect 내부에 넣기보다는 코드의 각 Effect는 별도의 독립적인 동기화 프로세스를 나타내는 것이 낫습니다. 

 

function ChatRoom({ roomId }) {
  useEffect(() => {
    logVisit(roomId);
  }, [roomId]);

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

 


반응형 값에 반응하는 Effect

의존성에는 반응형 값(props, state 및 렌더링 중에 계산되는 값)에만 반응합니다. 변하지 않는 값을 의존성으로 지정하는 것은 의미가 없습니다.

 

변경할 수 있는 값(전역 변수 포함)은 반응하지 않습니다. 이 값은 React 렌더링 데이터 흐름 외부에서 언제든지 변경할 수 있습니다. React는 Eeffect가 변경될 때 Effect를 다시 동기화할지 알 수 없습니다. 렌더링 도중(의존성을 계산할 때) 변경할 수 있는 데이터를 읽는 것은 렌더링의 순수성을 깨뜨리기 때문에 React의 규칙을 위반합니다. 대신, useSyncExternalStore를 사용하여 외부 변경할 수 있는 값을 읽고 구독해야 합니다. (ex location.pathname)

 

ref 객체 자체는 의존성이 될 수 있지만 ref.current은 의존성이 될 수 없습니다. 변경해도 다시 렌더링이 트리거 되지 않기 때문에 반응형 값이 아니며, React는 이 값이 변경될 때 effect를 다시 실행할지 알지 못합니다. 컴포넌트에 선언된 객체와 함수를 의존성으로 사용해서는 안됩니다. 컴포넌트가 렌더링 할 때마다 객체와 함수는 달라집니다. 

 

컴포넌트 내부에 useState에서 반환되는 set 함수와 useRef에서 반환되는 ref 객체는 안정적이며, 다시 렌더링해도 변경되지 않도록 보장됩니다. 안정된 값은 반응하지 않으므로 목록에서 생략할 수 있습니다.

 

** 객체와 함수를 의존성으로 사용하지 않는 것이 좋습니다. 렌더링 할 때마다 객체와 함수는 달라지며, 그러면 매번 동기화해야 합니다. 

 


** React18 공식 문서 보고 정리한 내용입니다.

https://ko-react-exy5xcwjj-fbopensource.vercel.app/learn/lifecycle-of-reactive-effects

 

반응형 effects의 생명주기 – React

The library for web and native user interfaces

ko.react.dev