[React Native] 웹과 웹뷰의 메시지 통신하기

호이·2023년 2월 27일
0

React Native

목록 보기
7/10

※ 이 포스트는 클래스형 컴포넌트를 기준으로 작성되었다.

1. 왜 필요한가?

웹에서 버튼을 눌러 웹뷰로 메시지를 전송하는 방법을 공부 중이였다. 이러한 방법을 사용하면 관리자가 사용자에게 특정 메시지를 푸시 알림 형태로 전송하는 것이 가능할 것 같았다.

2. 과정

웹뷰와 웹간의 통신하는 방법은 간단하였다. 하지만 웹에서 웹뷰로 메시지를 통신하는 방법을 찾아보았는데 다음과 같은 방법이 있다면 잘못된 방법이니 유의하길 바란다.

window.postMessage(event.data);

해당 방법을 사용하면 웹에서 웹으로 메시지를 주고 받을 수 있다. React같은 경우 다른 컴포넌트로 메시지를 보내는 것이 가능하다.
메세지를 받아서 출력하는 방법은 다음과 같다.

window.addEventListener("message", (event) => {
  console.log(event.data);
});

위의 코드는 웹 브라우저의 message라는 이벤트가 발생하면 해당 메세지의 데이터를 출력하는 코드이다. 흔히 자바스크립트에서 사용하는 addEventListener의 함수와 똑같다.

3. 결과

웹뷰와 웹의 메시지 통신하는 방법을 살펴볼 것이다. 다음의 코드를 constructor안에 추가하여 Ref를 생성한다.

this.webview = React.createRef();

다음의 코드를 웹뷰의 속성으로 추가하여 해당 웹뷰를 참조하도록 설정한다.

ref={this.webview}

웹뷰에서 웹이 로드가 완료된 후 웹으로 메시지를 전달하도록 설정한다.

onLoad={() => {
  this.webview.current.postMessage('hello Web!');
}}

웹에서 전달해준 메시지를 웹뷰에서 받을 수 있도록 웹뷰의 속성에 다음의 코드를 추가한다.

onMessage={(event) => {
  alert(event.nativeEvent.data);
}}

웹뷰의 전체 코드는 다음과 같다.

import React from "react";
import { WebView } from "react-native-webview";

export default class App extends React.Component {
  constructor(props) {
    super(props);
    this.webview = React.createRef();
  }

  render() {
    return (
      <WebView
        ref={this.webview}
        source={{ uri: "https://www.naver.com" }}
        onLoad={() => {
          this.webview.current.postMessage("hello Web!");
        }}
        onMessage={(event) => {
          alert(event.nativeEvent.data);
        }}
      />
    );
  }
}

다음으로 웹뷰로 메시지를 전송하는 간단한 웹을 만들어 볼 것이다. 웹뷰에서 보낸 메시지는 웹에서 수신하는 방법은 다음의 코드를 작성하면 된다.

document.addEventListener("message", (event) => {
  alert(event.data);
});

필자의 경우는 웹에서 버튼을 눌렀을 때 웹뷰로 메시지를 전송하도록 구현하였다. 다음의 코드를 작성하면 해당 기능을 구현할 수 있다.

document.querySelector("button").addEventListener("click", () => {
  window.ReactNativeWebView.postMessage("hello WebView!");
});

웹의 전체코드는 다음과 같다.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <button>메시지전송</button>
    <script>
      // 메시지 받기
      document.addEventListener("message", (event) => {
        alert(data);
      });
      // 메시지 전송
      document.querySelector("button").addEventListener("click", () => {
        window.ReactNativeWebView.postMessage(data);
      });
    </script>
  </body>
</html>
profile
기억하기 싫어서 기록하는 작은 공간

0개의 댓글