React Native: 웹앱 만들기 일지(2) - 웹과 앱의 통신
앱 내부에 web을 띄워주는 것이기 때문에 앱과 웹이 서로 통신하는 것이 되게 중요합니다. 서로 통신하는 법을 알아봅시다.
웹 -> 앱
웹 코드
//Next.js 코드
export default function PostMessageWebToAppPage() {
const onClick = () => {
// 메시지 보내는코드
}
return (
<button onclick={onClick}>앱으로 데이터 보내기</button>
)
}
버튼을 누르면 앱으로 메시지를 보내는 코드를 함수 내부에 작성하면 되겠죠.
그러고 싶을 때 사용하는 함수가 window.ReactNativeWebView.postMessage() 이구요.
파라미터에 보내고 싶은 메시지를 작성하면 되겠죠. 바나나라고 보내볼까요.
//Next.js 코드
export default function PostMessageWebToAppPage() {
const onClick = () => {
window.ReactNativeWebView.postMessage("Banana")
}
return (
<button onclick={onClick}>앱으로 데이터 보내기</button>
)
}
이렇게 써주면 아주 쉽게 보낼 수 있는데요. 문제는 해당 메서드는 웹의 window 내부에 존재하지 않아요. 아마 TS watcher? 가 빨간줄을 신명나게 그어줄겁니다. 다행인건 RN 앱 내부에는 존재하기에 앱에서는 오류가 안 나요. 그래서 타입을 직접 추가해주면 되는데.
declare const window: Window & {
ReactNativeWebView: {
postMessage: (message: string) => void;
};
};
이렇게 가장 위에 타입을 명시해주면 오류가 나지 않습니다.
앱에서 받기
앱에서 받는 건 더 쉽구요.
import { SafeAreaView } from "react-native-safe-area-context";
import WebView from "react-native-webview";
export default function PostMessageWebToAppPage() {
const address = "???";
return (
<SafeAreaView style={{ flex: 1 }}>
<WebView
source={{
uri: `${address}:3000/section03/03-02-post-message-web-to-app`,
}}
onMessage={(event) => {
if (!event.nativeEvent.data) return;
console.log("web에서 보내준 데이터", event.nativeEvent.data);
}}
/>
</SafeAreaView>
);
}
웹뷰 컴포넌트에 onMessage라는 함수를 적어주시면 됩니다.
파라미터로 event 객체를 받고, event.nativeEvent.data 에 웹에서 보내는 데이터가 들어있어요.
앱 -> 웹
이제는 반대로 통신하는 법도 알아야겠죠. 그리 어렵지 않아요.
앱
export default function PostMessageAppToWebPage() {
const address = "???";
const onPressButton = () => {
// 메시지 보내는 로직
};
return (
<SafeAreaView style={{ flex: 1 }}>
<WebView
source={{
uri: `${address}:3000/section03/03-03-post-message-app-to-web`,
}}
/>
<Button onPress={onPressButton} title="Web한테 데이터 보내기" />
</SafeAreaView>
);
}
이렇게 앱코드가 있구요. onPressButton 내부에 메시지를 보내는 로직을 작성하면됩니다.
그런데 웹뷰는 여러개를 가질 수 있기 때문에 어떤 웹뷰에게 메시지를 보내줄거냐? 를 정의해줘야 합니다.
웹뷰를 직접 참조하기 위해서 useRef 를 사용하면 됩니다.
export default function PostMessageAppToWebPage() {
const address = "???";
const webviewRef = useRef<WebView>(null);
const onPressButton = () => {
webviewRef.current?.postMessage("apple")
};
return (
<SafeAreaView style={{ flex: 1 }}>
<WebView
ref = {webviewRef}
source={{
uri: `${address}:3000/section03/03-03-post-message-app-to-web`,
}}
/>
<Button onPress={onPressButton} title="Web한테 데이터 보내기" />
</SafeAreaView>
);
}
useRef의 타입에는<WebView>를 정의해줍시다.ref = {webviewRef}로 웹뷰를 직접 연결해주구요.webviewRef.current?.postMessage("메시지")로 참조한 웹뷰에 메시지를 보내주면 됩니다.
웹
웹도 어렵지 않아요. 이벤트리스너를 통해서 메시지를 계속 감시하게 만듭시다. 단, 안드로이드, IOS 의 객체가 조금 다르니 이것만 주의해주면 될 것 같네요.
export default function PostMessageAppToWebPage() {
useEffect(() => {
// 1. 안드로이드에서 대기
document.addEventListener("message", (message: any) => {
alert(`앱에서 보내준 데이터 + ${message.data}`);
});
// 2. IOS에서 대기
window.addEventListener("message", (message: any) => {
alert(`앱에서 보내준 데이터 ${message.data}`);
});
}, []);
return (
<>
<div>저는 Web입니다.</div>
</>
);
document.addEventListener("message", (message: any) => {}: document는 안드로이드window.addEventListener("message", (message: any) => {}: window는 IOS에요.- 시간이 걸리는 작업이니
useEffect내부에 넣어주면 깔끔하겠죠.
이렇게 웹과 앱이 서로 통신하는 방법을 조금 알아봤구요. 그리 어렵진 않다 그죠?
2026년 7월 4일 AM 11:56
로그인 필요