app

김태헌

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

댓글 닫기
댓글이 없습니다.
로그인 필요