React 부모 새창(window.open) data refresh 커스텀훅

SangminL96·2022년 6월 10일
0

안녕하세요. 웹사이트중에 새창(자식창)을 띄우고
어떠한 이벤트를 완료 하였을때 부모창에서 데이터를 다시 받아오게 할 수 있는 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 : 지금 회사가 아닌 전 직장에서 관리자 사이트 배송 운송장번호 등록 및 수정등 새창(자식창)에서 이루어지고 부모창 데이터를 리프레쉬를 시켜야하는 기능이 필요했고 구글링을 통해 알게된 커스텀 훅이다. 현 직장에서도 유용하게 사용중이다.

profile
안녕하세요

0개의 댓글