useEffect
는 컴포넌트를 외부 시스템과 동기화 시킬수 있는 React 훅이다.
useEffect(setup, dependencies?)
컴포넌트의 최상위 레벨에서 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]);
// ...
}
setup
: Effect의 로직이 포함된 함수. 선택적으로 클린업 함수를 반활할 수 있다.
컴포넌트가 DOM에 추가되면(componentDidMount?) setup
함수를 실행하고, dependency array에 위치한 dependent한 값들이 변경되어 re-rendering할때마다 새 값으로 setup
함수를 실행한다.
또 컴포넌트가 DOM에서 제거되면 React는 마지막으로 클린업 함수를 실행한다. (umount, 컴포넌트가 화면에서 사라지는 것)
dependencies
: setup 코드 내에서 참조하는 모든 reactive한 값들의 리스트. reactive한 값들은 props, state, 컴포넌트 본분 내부에서 직접 선언한 변수와 함수를 포함한다.
dependency array
를 넘겨줄 때useEffect(() => {
// ...
}, [a, b]); // Runs again if a or b are different
초기 component가 mount된 이후와 a,b의 변경점이 생기면 re-rendering되고 setup
함수가 실행된다dependency array
를 넘겨줄 때useEffect(() => {
// ...
}, []); // Does not run again (except once in development)
초기 component가 mount된 이후(초기 렌더링)만 setup
함수가 실행된다dependency array
를 안넘겨줄 때useEffect(() => {
// ...
}); // Always runs again
디펜던시 어레이를 넘겨주지 않으면, 컴포넌트의 모든 렌더링(초기 렌더링 + 리렌더링) 이후 Effect(setup 함수)가 실행된다.dependency array중 일부가 컴포넌트 내부에 정의된 오브젝트 또는 함수일 경우 Effect가 필요 이상으로 자주 다시 실행될 위험이 있고, 이럴경우 성능저하의 원인이 될 수 있다.
만약 브라우저가 화면을 다시 그리지 못하도록 차단해야 하는 경우라면, 즉 화면에 표시되지 않기를 원하는 경우 useEffect
대신 useLayoutEffect
를 사용해야 한다.
client side 에서만 실행된다! server rendering에서는 실행되지 않는다.
컴포넌트가 페이지에 표시되는 동안 외부 API또는 라이브러리에 연결 상태를 유지해야하는 경우를 예시로 들어보자.
먼저 useEffect
를 컴포넌트 최상단에서 호출하고 사용하자.
리액트는 필요할때마다 setup함수와 cleanup함수를 호출하는데, 이는 여러번 발생할 수 있다.
Effect를 작성할때, component mount, update, unmount 어느 단계에 있는지보다, 독립적인 프로세스로 작성하고 한번에 하나의 셋업/클린업 주기만 생각하자.