HTML 생명주기
DOMContentLoaded – 브라우저가 HTML을 전부 읽고 DOM 트리를 완성하는 즉시 발생합니다. 이미지 파일(img)이나 스타일시트 등의 기타 자원은 기다리지 않습니다.
load – HTML로 DOM 트리를 만드는 게 완성되었을 뿐만 아니라 이미지, 스타일시트 같은 외부 자원도 모두 불러오는 것이 끝났을 때 발생합니다.
beforeunload/unload – 사용자가 페이지를 떠날 때 발생합니다.
출처 : https://ko.javascript.info/onload-ondomcontentloaded#ref-2797
1. DOMContentLoaded – DOM이 준비된 것을 확인한 후 원하는 DOM 노드를 찾아 핸들러를 등록해 인터페이스를 초기화할 때
2. load – 이미지 사이즈를 확인할 때 등. 외부 자원이 로드된 후이기 때문에 스타일이 적용된 상태이므로 화면에 뿌려지는 요소의 실제 크기를 확인할 수 있음
3. beforeunload – 사용자가 사이트를 떠나려 할 때, 변경되지 않은 사항들을 저장했는지 확인시켜줄 때
4. unload – 사용자가 진짜 떠나기 전에 사용자 분석 정보를 담은 통계자료를 전송하고자 할 때
/**************************************************************************************
* 브라우저 탭 닫기 이벤트 핸들러
*
**************************************************************************************/
// eslint-disable-next-line react-hooks/exhaustive-deps
const handleTabClosed = useCallback(
async (event) => {
event.preventDefault();
//:TODO 탭닫기시 내가 원하는 로직
👉 ...
[],
);
useEffect(() => {
window.addEventListener('beforeunload', handleTabClosed);
return () => {
window.removeEventListener('beforeunload', handleTabClosed);
};
}, [handleTabClosed]);
💀 문제
처음 렌더링시 useEffect 에 설정한 이벤트 핸들러가
동작한다.
탭을 끌때만 작동해야 했지만 초기 렌더링시에
useEffect 내부 로직이 작동되었다..
🤩 해결
리엑트 생명주기 함수의 componentDidMount() 를 이용했다.
현재 개발은 함수형이기 떄문에 "UseDidMountEffect"라는 훅을 아래와 같이 만들었다.
import React, {useEffect, useRef} from 'react'; . const UseDidMountEffect = (func, deps) => { const didMount = useRef(false); . useEffect(() => { if (didMount.current) func(); else didMount.current = true; }, deps); }; . export default UseDidMountEffect;
/**************************************************************************************
* 브라우저 탭 닫기 이벤트 핸들러
*
**************************************************************************************/
// eslint-disable-next-line react-hooks/exhaustive-deps
const handleTabClosed = useCallback(
async (event) => {
event.preventDefault();
//:TODO 탭닫기시 내가 원하는 로직
👉 ...
[],
);
UseDidMountEffect(() => {
window.addEventListener('beforeunload', handleTabClosed);
return () => {
window.removeEventListener('beforeunload', handleTabClosed);
};
}, [handleTabClosed]);
참고