반응형
진행중인 프로젝트에서 신규 개발을 진행하던 중 웹뷰로 띄워지는 화면에서 특정 버튼 클릭시 앱 내에서 필요한 화면으로 이동해야 하는 기능을 구현하게 되었다.
이전에 지도를 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 });
}
};
반응형
'FE Development > React-Native' 카테고리의 다른 글
CodePush 적용 (1) | 2022.01.17 |
---|---|
트러블 슈팅 - FlatList 최적화 (0) | 2022.01.13 |
트러블 슈팅 - 키보드가 UI를 가리는 경우 (KeyboardAvoidingView) (0) | 2021.11.25 |
React Native 보안편 소스코드 난독화 - Android (0) | 2021.11.14 |
React Native Firebase-Crashlytics 적용 (0) | 2021.11.12 |
댓글