window is not defined
Next js에서는 window 객체를 사용할 수 없다 프론트 서버에서 작동을 하고 클라이언트로 옮겨주기 때문에
브라우저 객체인 window 객체를 사용하려면 아래와 같은 방법을 사용하곤 했다.
if(typeof window !== undefined) {
window ~~ 객체 사용 가능
}
useEffect는 프론트 서버에서 동작하는것이 아닌 DOM 생성 후 실행되는 react hook 이기 때문에,
window를 체크하지 않아도 작동한다.
useEffect(()=>{
window ~~ 객체 사용 가능
},[])
import dynamic from 'next/dynamic'
const Chart = dynamic(() => import('react-apexcharts'), { ssr: false });
react-apexcharts 차트 옵션은 window 객체가 필요하기 때문에, ssr 옵션을 false로 작성하여 에러를 방지할 수 있다.
일반적으로 webview를 통해 네이티브 앱과 웹사이트간에 데이터를 주고 받는 방법은
특정변수명에 데이터를 실어서 보내준다.
아래는 현재 webview를 사용하는 플러터 코드중에 일부분이다.
return WebView(
initialUrl: '웹뷰주소',
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController webViewController) {
_controller.complete(webViewController);
_crxl = webViewController;
},
onPageStarted: (url) {
_crxl.runJavascript("myMessage=$nativeToJs");
});
myMessage라는 변수에 플러터 데이터를 담아서 우리의 웹뷰로 보내줄 수 있는데,
웹뷰에서는 보통 window.myMessage라는 변수에 담겨있는것을 확인할 수 있다.
(리액트네이티브와,플러터는 window.변수명 이렇게 담겨왔지만, 일반적인 안드로이드, 스위프트는 사용해본적이 없어서 아닐 수 도 있다.)
위에서 next js 에서 window 객체를 사용하려면
typeof 사용하면된다고 했으니 사용해서 데이터를 받아서 웹의 변수로 담아보자.
if(typeof window !== undefined) {
console.log(window.myMessage);
}
작성하고 보니 아래와같은 에러를 마주쳤을지도 모른다.
에러메세지는 다음과 같다.
Property '' does not exist on type 'Window & typeof globalThis'
아니 위에서 window 객체 쓰는법 알려줬는데 왜 에러발생함??
window 객체에서는 보통 정해진 window 객체만 담겨있다.
웹 콘솔에서 window를 입력해보면 아래와같이 사용할 수 있는 window 객체들을 볼 수 있는데
기본적인 window객체에는 myMessage라는 함수,변수가 선언되어있지 않다.
왜냐하면 myMessage라는 함수,변수는 우리 네이티브 앱에서 웹으로 전달만했을뿐이지, 기존에 있는 window객체는 아니기 때문이다.
방법은 나름 간단한데,
Next js window 객체에 네이티브에서 전달한 변수,함수가 있다고 선언해주면 되는데
타입스크립트 선언 키워드인 declare를 사용하면된다.
나는 사진과같이 types라는 폴더밑에 index.d.ts 파일을 생성했다.
Window 인터페이스에 우리가 네이티브를 통해 받을 변수,함수의 타입을 지정해주면 해결된다.
index.d.ts
export {};
declare global {
interface Window {
JavaScriptChannel: any;
myMessage: any;
}
}
만약 그래도 오류가 해결되지 않는다면,?
tsconfig.json 파일에 해당부분을 추가하여 저장하고 프로젝트 폴더를 껐다 켜보자
"typeRoots": ["./node_modules/@types", "./src/common/types"]