브라우저 탭 닫을시 이벤트 핸들링 회고

roberto·2022년 7월 25일
0
post-thumbnail

어플리케이션을 탭으로 관리하고 있었다.

그에 따라 탭닫을시 탭마다 관리하고 있는 토큰을 삭제 시켜줘야 했다

브라우저 탭닫을시 핸들링을 위해 HTML 생명주기를 살펴 봐야한다

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 – 사용자가 진짜 떠나기 전에 사용자 분석 정보를 담은 통계자료를 전송하고자 할 때

사용자가 페이지를 떠날때(닫을때)의 이벤트가 필요했고

"beforeunload" 가 내상황과 딱 맞는 핸들러 였다

	/**************************************************************************************
	 * 브라우저 탭 닫기 이벤트 핸들러
	 *
	 **************************************************************************************/
	
    // 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]);

참고


profile
medium 으로 이전했습니다

0개의 댓글