[React] 새창열고 데이터 받기

22_gas·2024년 9월 5일

React 관련지식

목록 보기
3/3

개요

여러가지 고객이 원하는 페이지를 만들다보면 새창을 열어서 데이터를 받아야 할 때가 있다.
예전에 Spring에서는 parent. 아니면 window.opener 로 전달해줬던거 같은데 React에선 쓸수없다.(왜 그런지는 사실 잘 모른다.)

해결방안

gpt한테 물어보기

GPT야 React에서 window.open으로 팝업창으로 띄워서 작성한 데이터를 받는방법을 알려줘

부모창

 	//...
	const [data, setData] = useState(null);
	const handleOpenPopup = () => {
    	const popup = window.open('/popup', 'Popup', 'width=600,height=400');
      	const _timer = setInterval(() => {
         	if(popup.closed){
              if(popup.dataFromPopup{
                setData(popup.dataFromPopup);
              }
            }
        }, 500);
    }
	

자식창

	const sendToParent = () => {
      if(window.opener){
        window.opener.dataFromPopup = inputValue;
        window.close();
      }
    }

해보진 않았다. setInterval로 사용하는 부분이어서 성능이 안좋지 않을까 하는 생각이다.
간단히 구현할때는 좋아보인다.

'storage' 이벤트 이용

window에 이벤트중에 'storage'를 이용하는 방식이 있다.

storage 이벤트는 localStorage, sessionStorage 의 변경이 일어나면 이벤트가 발생한다.

부모창

  	//...
	//store이벤트를 받아서 처리해주는 부분을 만든다.
	const storageEvent = e => {
    	const popupData = localStroage.getItem('popup');
      	if(popupData){
        	window.removeEventListener('storage', storageEvent);
        }
    }
    
    const handleOpenWindow = () => {
   		window.open('/popupDetail', '팝업', '');

    	localStorage.removeItem('popup');

    	window.addEventListener('storage', storageEvent);
    }
    
    
    return (
    	<>
      		<button onClick={handleOpenWindow}>OPEN!</button>
      	</>
    )

자식창

	//...
	const handleClick = () => {
		const _saveData = {
        	age: 10,
          	name: 'name'
        }
        localStorage.setItem('popup', JSON.stringify(_saveData);
        window.close();
    }

상태관리 라이브러리 활용

위에서 어차피 storage 이벤트를 판단하는거라면, 상태관리에서 데이터를 저장할때 localStorage나 SessionStorage를 활용할수 있다고 알고있어 jotai라는 라이브러리를 사용해보기로 했다.

atoms.js

	export const userDataAtom = atomWithStorage('userData', null);

부모창

	//...
	const [userData, setUserData] = useAtom(userDataAtom);

	//...
	useEffect(() => {
    	console.log('userData', userData);
  	},[userData]);

자식창

	//...
	const [userData, setUserData] = useAtom(userDataAtom);
	//...
	const handleSave = () => {
      	const _saveData = {
          //...
        }
      	//...
    	setUserData(JSON.stringify(_saveData));
      	window.close();
    }

끗!

profile
전 아직 모르는게 많아요

0개의 댓글