본문 바로가기
FE Development/React-Native

react-native-webview을 통해 띄운 웹과 앱간의 인터랙션

by 개발자 데이빗 2022. 1. 10.

진행중인 프로젝트에서 신규 개발을 진행하던 중 웹뷰로 띄워지는 화면에서 특정 버튼 클릭시 앱 내에서  필요한 화면으로 이동해야 하는 기능을 구현하게 되었다.

이전에 지도를 webview로 띄웠던 경우에는 지도 웹 또한 직접 구현하였기 때문에 JavaScript의 postMessage를 활용한 경험이 있었지만 이번에는 해당 웹을 수정하기는 어려운 상황이었고 react-native-webview에서 제공되는 injectedJavaScript를 이용해 구현하기로 하였다.

 

WebView 컴포넌트 예시코드

<WebView
  javaScriptEnabled
  originWhitelist={['*']}
  source={{ uri: 'https://beenlog.tistory.com/' }}
  onMessage={handleOnMessage}
  injectedJavaScript={handleWebViewButton}
  injectedJavaScriptForMainFrameOnly={false}
  ref={webviewRef}
/>

 

 

 injectedJavaScript 예시코드

  • 웹뷰가 로드될때 특정 javascript 코드를 심어줄 수 있다.
    아래의 예시는 클릭한 버튼의 value 속성값을 받아 해당하는 상세 정보를 보여주는 페이지로 이동하는 경우이다.
  • 해당 버튼은 a태그였으므로 e.preventDefault()를 이용해 기존의 링크를 작동하지 않게 한다.
  • 특이한 점은 let, const, arrow function, forEach 등 es6 문법을 사용하지 못한다는 점이다 (에러 발생)
  • 동적으로 이벤트를 할당해주어야 했기 때문에 document 객체에 클릭 이벤트를 걸고 어떤 버튼을 클릭했는지에 따른 분기처리를 통해 구현하였다.
  const handleWebViewButton = `
    document.addEventListener("click", function (e) {
        e.preventDefault();
        var target = e.target;
        if (target.innerText === '자세히 보기') {
            window.ReactNativeWebView.postMessage(JSON.stringify({
                type: 'navigateToDetail',
                message: target.attributes.value.value,
            }));
        };
    });
  `;

 

 

onMessage 예시코드

  • 웹으로부터 받은 메세지를 파싱해 상세 페이지로 이동하고 params에 value 속성값을 넘겨 해당 페이지에서 api 요청을 할 수 있도록 구현하였다.
  const handleOnMessage = ({ nativeEvent: { data } }: WebViewMessageEvent) => {
    const dataFromWebView: { type: string, message: string } = JSON.parse(data);
    const detailClick = get(dataFromWebView, 'type') === 'navigateToDetail';
    const detailId = get(dataFromWebView, 'message');
    if (detailClick) {
      navigation.navigate(screens.DETAIL_PAGE, { keyword: dataFromWebView.message, detailId });
    }
  };

 

 

 

댓글