안녕하세요. 웹사이트중에 새창(자식창)을 띄우고
어떠한 이벤트를 완료 하였을때 부모창에서 데이터를 다시 받아오게 할 수 있는 hook을 알려드릴려고합니다.
흔히 사이트에서 볼 수 있는 문의 게시판 입니다.
상단에 문의하기를 클릭후 문의할 수 있는 새창이 띄우는 형식이 많습니다.
이때 새창에서 문의 내용을 입력후 확인 버튼 클릭시 새창을 닫고 부모창 데이터를 리프레쉬 시켜줘야 새로 등록된 문의를 볼 수 있습니다.
부모창과 자식창과의 이벤트 플래그를 받을 수 있는 간단한 커스텀 훅 소개 드리겠습니다.(저도 구글링해서 작성한 코드입니다.)
import { useEffect, useState, useRef } from 'react';
const useCrossTabState = (stateKey, defaultValue) => {
const [state, setState] = useState(defaultValue);
const isNewSession = useRef(true);
useEffect(() => {
// isNewSession 현재 보고 있는 창을 의미하고 true일때만 실행되고 실행후 false를 봐꾸어 실행 중지 시킨다.
// 이 조건이 없으면 부모창과 자식창과의 플래그를 계속 주고 받아 무한 루프돌게 된다.
if (isNewSession.current) {
const currentState = localStorage.getItem(stateKey);
if (currentState) {
setState(JSON.parse(currentState));
} else {
setState(defaultValue);
}
isNewSession.current = false;
return;
}
//위에 isNewSession.current true일때 state값이 바뀌고 난후 로컬스토리지에 저장해준다
try {
localStorage.setItem(stateKey, JSON.stringify(state));
} catch (error) {
console.error(error);
}
}, [state, stateKey, defaultValue]);
// storage 이벤트, 이로직이 있지 않으면 로컬스토리지가 바뀌더라도 부모창에서 감지 불가.
useEffect(() => {
const onReceieveMessage = e => {
const { key, newValue } = e;
if (key === stateKey) {
setState(JSON.parse(newValue));
}
};
window.addEventListener('storage', onReceieveMessage);
return () => window.removeEventListener('storage', onReceieveMessage);
}, [stateKey, setState]);
return [state, setState];
};
export default useCrossTabState;
const [tableRefetch, setTableRefetch] = useCrossTabState('tableRefetch', false);
useEffect(() => {
console.log('데이터 패치');
//우리회사는 useSWR사용하기때문에 뮤테이트하여 패치해준다
dataMutate();
setTableRefetch(false);
}, [tableRefetch, setTableRefetch, dataMutate]);
const [_, setTableRefetch] = useCrossTabState('tableRefetch', false);
const onClick = ()=>{
setTableRefetch(true)
window.close()
}
<button onClick={onClick}>확인<button/>
TMI : 지금 회사가 아닌 전 직장에서 관리자 사이트 배송 운송장번호 등록 및 수정등 새창(자식창)에서 이루어지고 부모창 데이터를 리프레쉬를 시켜야하는 기능이 필요했고 구글링을 통해 알게된 커스텀 훅이다. 현 직장에서도 유용하게 사용중이다.