useEffect를 사용하면 ComponentDidMount, ComponentDidUpdate, ComponentWillUnmount를 하나의 함수로 대체할 수 있습니다.
useEffect(() => {
... 로직
}, []);
로직 부분에 실행할 코드가 들어갑니다. 그러면 컴포넌트가 마운트될 때 실행되고 끝입니다.
const useFavicon = href => {
const [favi, setFavi] = useState(href);
useEffect(() => {
const link = document.querySelector("link[rel*='icon']") || document.createElement("link");
link.type = "image/x-icon";
link.rel = "shortcut icon";
link.href = favi;
document.getElementsByTagName("head")[0].appendChild(link);
}, [favi]);
return setFavi;
}
useEffect의 두번째 파라미터인 [] 배열을 deps라고 하며 이 안에 웹페이지의 favicon을 바꾸는 코드입니다.
useFavicon이라는 훅을 직접 만들었습니다. 선언시에 파라미터로 href에 해당하는 값을 넣어주면 ComponentDidMount의 효과로 그 값에 해당하는 파비콘을 보게 됩니다.
그리고 setFavi를 리턴했으므로 const faviconSetter = useFavicon(...); 이런 식으로 useFavicon을 선언하고 faviconSetter(...) 이런 식으로 호출하게 되면 favi라는 state가 변경되면서 useEffect의 로직이 실행됩니다.
그러면 그것은 결국 파비콘을 변경하는 효과입니다.
이와 같이, deps 안에 어떠한 값이 들어가면 그 값이 변경될 때마다 useEffect 안의 코드가 실행됩니다. 이것은 ComponentDidUpdate와 동일한 효과입니다.
여기서 favicon이란 브라우저 내 탭에서의 타이틀 왼쪽에 있는 아이콘을 뜻합니다. 밑의 예시에서는 티스토리의 상징인 물방울 무늬의 T가 favicon입니다.
...
const [x, setX] = useState();
const [y, setY] = useState();
const update = e => {
setX(e.x);
setY(e.y);
}
useEffect(() => {
window.addEventListener("mousemove", update);
return () => {
window.removeEventListener("mousemove", update);
}
}, []);
...
위의 코드는 마우스가 움직일 때마다 x, y 값이 바뀌는 동작을 합니다.
return 안의 부분을 클린업 함수라고 부르며 해당 컴포넌트가 언마운트될 때 실행됩니다.