useEffect() 함수는 리액트 컴포넌트가 렌더링 될 때마다 특정 작업(Side Effect)을 실행할 수 있도록 하는 리액트 Hook 이다.
여기서 SideEffect 는 컴포넌트가 렌더링 된 이후에 비동기로 처리되어야 하는 부수적인 효과들을 뜻한다.
useEffect는 component가 mount 됐을 때, unmout 됐을 때, update 됐을 때, 특정 작업을 처리할 수 있다
즉, 클래스형 컴포넌트에서 사용할 수 있었던 생명주기 매소드를 함수형 컴포넌트에서도 사용할 수 있게 된 것을 말한다.
useEffect(function,deps)
function : 수행하고자 하는 작업 (리액트가 기억 했다가 DOM 업데이트 후 불러내는 함수)
deps : 배열 형태이며 , 배열 안에는 검사하고자 하는 특정 값 or 빈배열
deps에 특정 값을 넣게 되면 컴포넌트가 mount 될 때와 지정한 값이 업데이트 될 때 useEffect를 실행한다.
useEffect(() = >{
console.log('mount');
},[])
useEffect(() = >{
console.log('렌더링 될 때 마다');
})
useEffect(() = >{
console.log('update');
},[name])
특정 값이 업데이트 될 때 실행하고 싶다면, deps 위치의 배열 안에 검사하고 싶은 값을 넣어줍니다.
하지만 업데이트 될 때만 실행되는 것이 아니라 마운트 될 때도 실행된다. 만약 업데이트 될 때만 실행시키고 싶다면 아래와 같은 방법을 사용한다
const mounted = useRef(false)
useEffect(() =>{
if(!mounted.current){
mounted.current = true;
}else{
console.log(name);
}
},[name])
mounted는 useRef(false)로 초기화됩니다. 즉, mounted.current의 초기값은 false입니다.
useEffect 훅이 실행됩니다. 이 훅은 name이 변경될 때마다 실행되도록 되어있지만, 처음 렌더링될 때도 한 번 실행됩니다.
!mounted.current 조건이 참(true)이므로 if 블록이 실행됩니다. 따라서 mounted.current = true;가 실행되어 mounted.current의 값이 true로 변경됩니다.
이 시점에서 console.log(name);는 실행되지 않습니다.
name이 변경될 때:
name이 변경될 때마다 useEffect가 다시 실행됩니다.
이제 mounted.current는 true이기 때문에 !mounted.current 조건이 거짓(false)이 됩니다.
따라서 else 블록이 실행되어 console.log(name);가 실행됩니다. 이 시점에서 name의 현재 값이 콘솔에 출력됩니다.
이후 name이 또 변경될 때마다:
mounted.current는 이미 true로 설정되어 있기 때문에 계속해서 else 블록이 실행되며 console.log(name);가 실행됩니다.
3.componentDidUnMount
const mounted = useRef(false);
useEffect(() => {
if (!mounted.current) {
mounted.current = true;
} else {
console.log(name);
}
// 정리(cleanup) 함수
return () => {
console.log('컴포넌트가 언마운트되었습니다.');
};
}, [name]);
언마운트 될 때만 cleanup 함수를 실행하고 싶다면, 두 번째 파라미터에 빈 배열을 넣고 return 문과 cleanup 함수를 선언해주면 된다.
특정 값이 업데이트 되기 직전에 cleanup 함수를 실행하고 싶다면 deps 배열 안에 검사하고 싶은 값을 넣어준다.
정리 함수(clean up) 는 메모리 누수를 방지하고, 이벤트 리스너나 타이머 등의 리소스를 해제하는 데 유영하다.
예를 들어 웹 소켓 연결을 닫거나, 구독을 취소하거나, 이벤트 리스너를 제거하는 등의 작업을 수행할 수 있다.