https://ko.reactjs.org/docs/hooks-effect.html
Effect Hook을 사용하면 함수 컴포넌트에서 side effect를 수행할 수 있습니다.
React의 class 생명주기 메서드에 친숙하다면, useEffect Hook을 **componentDidMount**와
**componentDidUpdate**, **componentWillUnmount**가 합쳐진 것으로 생각해도 좋습니다.
**Class를 사용하는 예시**
React의 class 컴포넌트에서 render 메서드 그 자체는 side effect를 발생시키지 않습니다.
이때는 아직 이른 시기로서 이러한 effect를 수행하는 것은 React가 DOM을 업데이트하고 난 이후입니다.
React class에서 side effect를 componentDidMount와 componentDidUpdate에 두는 것이 바로 이 때문입니다.
**useEffect가 하는 일은 무엇일까요?**
useEffect Hook을 이용하여 우리는 React에게 컴포넌트가 렌더링 이후에 어떤 일을 수행해야하는 지를 말합니다.
React는 우리가 넘긴 함수를 기억했다가(이 함수를 ‘effect’라고 부릅니다) **DOM 업데이트를 수행한
이후**에 불러낼 것입니다.
**useEffect는 렌더링 이후에 매번 수행되는 걸까요?**
네! 기본적으로 첫번째 렌더링과 이후의 모든 업데이트에서 수행됩니다.
마운팅과 업데이트라는 방식으로 생각하는 대신 effect를 렌더링 이후에 발생하는 것으로
생각하는 것이 더 쉬울 것입니다. **React는 effect가 수행되는 시점에 이미 DOM이 업데이트되었음을
보장합니다.**
import React, { useState, useEffect } from 'react';
function FriendStatus(props) {
const [isOnline, setIsOnline] = useState(null);
useEffect(() => {
function handleStatusChange(status) {
setIsOnline(status.isOnline);
}
ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
// effect 이후에 어떻게 정리(clean-up)할 것인지 표시합니다.
return function cleanup() {
ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
};
});
if (isOnline === null) {
return 'Loading...';
}
return isOnline ? 'Online' : 'Offline';
}
**effect에서 함수를 반환하는 이유는 무엇일까요?**
이는 effect를 위한 추가적인 정리(clean-up) 메커니즘입니다.
모든 effect는 정리를 위한 함수를 반환할 수 있습니다.
이 점이 구독(subscription)의 추가와 제거를 위한 로직을 가까이 묶어둘 수 있게 합니다.
**React가 effect를 정리(clean-up)하는 시점은 정확히 언제일까요?**
React는 컴포넌트가 마운트 해제되는 때에 정리(clean-up)를 실행합니다.
effect는 한번이 아니라 렌더링이 실행되는 때마다 실행됩니다.
React가 다음 차례의 effect를 실행하기 전에 이전의 렌더링에서 파생된 effect 또한 정리하는
이유가 바로 이 때문입니다.
**팁: Effect를 건너뛰어 성능 최적화하기**
클래스 컴포넌트의 경우에는 componentDidUpdate에서 prevProps나 prevState와의 비교를 통해
이러한 문제를 해결할 수 있습니다.
componentDidUpdate(prevProps, prevState) {
if (prevState.count !== this.state.count) {
document.title = `You clicked ${this.state.count} times`;
}
}
특정 값들이 리렌더링 시에 변경되지 않는다면 React로 하여금 effect를 건너뛰도록 할 수 있습니다.
useEffect의 선택적 인수인 두 번째 인수로 배열을 넘기면 됩니다.
useEffect(() => {
document.title = `You clicked ${count} times`;
}, [count]); // count가 바뀔 때만 effect를 재실행합니다.