window 팝업창의 데이터 전달

devHagaa·2023년 8월 16일
2

Javascript

목록 보기
8/8

React로 프로젝트를 진행하던 중 모달이 아닌 팝업창을 통해 데이터를 전달하고 전달 받는 케이스가 생겼다.

모달도 아니고 새 팝업창인데 어떻게 데이터를 주고 받아야하나 고민하던 차에 구글링과 chatGPT의 도움으로 해결하여 기록하고자 한다.

부모창 -> 자식창 데이터&함수 전달

window.open 을 사용하여 팝업창을 열 때, 부모창에서 자식창에게 데이터를 넘겨주는 것은 직접적으로 불가능하다. 이는 브라우저의 보안 정책 때문이다. 그러나, 몇 가지 방법을 통해 데이터를 전달할 수 있다.

LocalStorage 또는 SessionStorage 사용

부모창에서 LocalStorage 또는 SessionStorage에 데이터를 저장하고, 팝업창이 열릴 때 해당 저장소에서 데이터를 가져올 수 있다.

// 부모창
localStorage.setItem('sendData', JSON.stringify(sendData));
window.open('popup.html');

// 팝업창
const sendData = JSON.parse(localStorage.getItem('sendData'));

URL Parameter 사용

URL의 쿼리 파라미터를 통해 데이터를 전달할 수 있다. 하지만 이 방법은 전달할 수 있는 데이터의 크기가 제한적이며, 복잡한 데이터 구조를 전달하기 어렵다.

// 부모창
const checkedListString = JSON.stringify(checkedList);
window.open(`popup.html?checkedList=${encodeURIComponent(checkedListString)}`);

// 팝업창
const urlParams = new URLSearchParams(window.location.search);
const checkedList = JSON.parse(decodeURIComponent(urlParams.get('checkedList')));

PostMessage API 사용

API를 사용하면, 도메인, 프로토콜, 포트가 다른 창 간에 안전하게 데이터를 전달할 수 있다. 이 방법은 복잡한 데이터 구조를 전달하는 데 적합하다.

// 부모창
const popup = window.open('popup.html');
popup.postMessage({ sendData }, '*');

// 팝업창
window.addEventListener('message', (event) => {
 const { sendData } = event.data;
});

나는 목록에서 선택한 check박스의 id배열을 자식 팝업창으로 넘겨줘야 했는데 세가지 방법 중 첫번째 방법을 이용했다.

// 부모창

 const [checkedList, setCheckedLists] = useState([]);

//'상태변경' 버튼 클릭
  const _pupup = () => {
    if (checkedList.length < 1) {
      alert("상태를 변경할 목록을 선택해 주세요.");
      return;
    }

    window.open(
      "/searchConts",
      "_winPkg",
      "height=400, width=400, toolbar=no, scrollbars=no,resizable=yes"
    );
    
    // 로컬스토리지에 checkedList 값 저장
    localStorage.setItem("checkedList", JSON.stringify(checkedList));


	// window 객체에 parentCallback이라는 새로운 함수 추가
    window.parentCallback = () => {
      getContents();
      setCheckedLists([]);
    };
  };

localStorage setItem으로 checkedList라는 값을 저장시키는 방법을 사용했다.

window.parentCallback이라는 새로운 함수를 추가하여 이 함수가 실행될 때 getContents(새로운 리스트 데이터 조회)와 setCheckedLists(선택된 리스트 해제)를 동작하게 선언하였다.

자식창 -> 부모창의 데이터 수신&함수 실행

자식창에서 부모창의 데이터를 받기 위해 아까 localStorage에 저장한 값을 받아온다.

const concdss = JSON.parse(localStorage.getItem("checkedList"));

내 프로젝트에서는 concdss라는 변수명으로 받았다.

자식창에서 '저장' 버튼을 클릭했을 때 부모창의 함수를 실행해 보겠다.

// 저장
  const _postState = useCallback(() => {
    contentAPI
      .putContentStatus(concdss, consts, conrmk, token.id)
      .then(() => {
        localStorage.removeItem("checkedList");
        window.opener.parentCallback();
        window.close();
      })
      .catch((error) => {
        console.error("Error:", error);
      });
  });

저장 버튼을 클릭 했을 때, PUT method로 API를 호출하고 성공적으로 데이터를 보내면 localstorage에 저장한 checkedList 값을 삭제시켜준다.

부모창에 선언한 parentCallback함수를 실행시켜 새로운 데이터를 가져오고 체크박스를 전체 해제 시킨다.

profile
디자이너인가 퍼블리셔인가 프론트엔드개발자인가 정체성의 혼란을 겪는 개린이

1개의 댓글

comment-user-thumbnail
2023년 8월 16일

공감하며 읽었습니다. 좋은 글 감사드립니다.

답글 달기