React Native中WebView與html雙向通信遇到的坑
安卓、ios原生與html雙向通信相對簡單且成熟,但是React Native與html的雙向通信存在那么一丟丟的坑
一、參數(shù)配置
導(dǎo)包
import {<!--{cke_protected}{C}%3C!%2D%2D%20%2D%2D%3E--> WebView } from 'react-native-webview'使用
<WebView
ref={ref => this.webViewRef = ref}
source={{ uri: url }}
// source={{ html }}
javaScriptEnabled
useWebKit
allowFileAccess
startInLoadingState
onLoadStart={this.onLoadStart}
onError={this.onError}
onLoad={this.onLoad}
onLoadEnd={this.onLoadEnd}
renderLoading={this.renderLoading}
renderError={this.renderError}
javaScriptCanOpenWindowsAutomatically
onMessage={this.handleMessage}
injectedJavaScript={`(function() {window.postMessage = function(data) {window.ReactNativeWebView.postMessage(data)}})();`}
相關(guān)回調(diào)函數(shù)
onLoadStart = ({ nativeEvent }) => {
console.log('onLoadStart', nativeEvent)
}
onError = ({ nativeEvent }) => {
console.log('onError', nativeEvent)
}
onLoad = ({ nativeEvent }) => {
this.setState({ title: nativeEvent.title })
console.log('onLoad', nativeEvent)
}
onLoadEnd = ({ nativeEvent }) => {
console.log('onLoadEnd', nativeEvent)
}
renderLoading = () => {
console.log('renderLoading')
}
renderError = ({ nativeEvent }) => {
console.log('renderError', nativeEvent)
}
handleMessage = async ({ nativeEvent }) => {
const { actionType, extra } = nativeEvent.data && JSON.parse(nativeEvent.data) || {}
}
二、坑點(diǎn)
react-native-webview使用postMessage后H5不能監(jiān)聽問題
注意:這里安卓用document,ios用window,否則會出現(xiàn)react-native-webview使用postMessage后H5不能監(jiān)聽問題
/* 監(jiān)聽rn消息 */
const eventListener = nativeEvent => {
//解析數(shù)據(jù)actionType、extra
const {actionType, extra} = nativeEvent.data && JSON.parse(nativeEvent.data) || {}
}
//安卓用document,ios用window
window.addEventListener('message', eventListener);
document.addEventListener('message', eventListener);
RN的webview的onMessage監(jiān)聽不到的問題
injectedJavaScript={<!--{cke_protected}{C}%3C!%2D%2D%20%2D%2D%3E-->`(function() {window.postMessage = function(data) {window.ReactNativeWebView.postMessage(data)}})();`}注意這里要加上injectedJavaScript,它重寫window.postMessage方法解決了RN的webview的onMessage監(jiān)聽不到的問題
三、React Native與html雙向通信
3.1、RN發(fā)數(shù)據(jù)到WebView
RN通過postMessage發(fā)送數(shù)據(jù)
const temp = {
actionType: 'takePhoto',
extra: {
fileId: '1522501682737836034',
fileUrl: 'https://gongbao-phoenix.oss-cn-hangzhou.aliyuncs.com/test/330100/1/2022/05/06/2efb943b439146ed86db0ad920c7edaf.jpg',
originalFileName: 'E91FDC71-FD9C-49B9-B038-529C9CDC149B.jpg',
tag: 'not_use',
unionId: 'f143153ed07a428fa6308d6f73b1a2b9',
},
}
this.webViewRef.postMessage(JSON.stringify(temp))
webView接受數(shù)據(jù)
/* 監(jiān)聽rn消息 */
const eventListener = nativeEvent => {
const {actionType, extra} = nativeEvent.data && JSON.parse(nativeEvent.data) || {}
}
//安卓用document,ios用window
window.addEventListener('message', eventListener);
document.addEventListener('message', eventListener);
3.2、WebView發(fā)數(shù)據(jù)到RN
WebView通過postMessage發(fā)送數(shù)據(jù)
const action = {
actionType: 'viewPicture',
extra: {
pics: ['https://tva1.sinaimg.cn/large/e6c9d24ely1h0svk2jlcej20ps11ewld.jpg'],
defaultIndex: 0,
},
}
window.postMessage(JSON.stringify(action));
RN注冊onMessage接收
onMessage={<!--{cke_protected}{C}%3C!%2D%2D%20%2D%2D%3E-->this.handleMessage}handleMessage = async ({ nativeEvent }) => {
const { actionType, extra } = nativeEvent.data && JSON.parse(nativeEvent.data) || {}
}
四、demo源碼
import React, { Component } from 'react'
import {
DeviceEventEmitter,
StyleSheet,
} from 'react-native'
import { WebView } from 'react-native-webview'
import NavigatorBar from '../../components/NavigatorBar'
import { SafeAreaView } from '../../components'
export default class WebViewPage extends Component {
state = {
title: '',
showBackAction: false,
}
_autoCheckNavigationBar = nativeEvent => {
const { canGoBack } = nativeEvent
this.setState({ showBackAction: canGoBack })
DeviceEventEmitter.emit('showTabBar', !canGoBack)
}
onLoadStart = ({ nativeEvent }) => {
console.log('onLoadStart', nativeEvent)
}
onError = ({ nativeEvent }) => {
console.log('onError', nativeEvent)
}
onLoad = ({ nativeEvent }) => {
this.setState({ title: nativeEvent.title })
console.log('onLoad', nativeEvent)
}
onLoadEnd = ({ nativeEvent }) => {
console.log('onLoadEnd', nativeEvent)
this._autoCheckNavigationBar(nativeEvent)
}
renderLoading = () => {
console.log('renderLoading')
}
renderError = ({ nativeEvent }) => {
console.log('renderError', nativeEvent)
}
handleMessage = async ({ nativeEvent }) => {
const { actionType, extra } = nativeEvent.data && JSON.parse(nativeEvent.data) || {}
}
render() {
const { showBackAction } = this.state
const { url } = this.props || {}
return (
<SafeAreaView style={styles.container} hideBottomView={!showBackAction}>
<NavigatorBar
backAction={showBackAction && this.webViewRef.goBack}
title={this.state.title}
/>
<WebView
ref={ref => this.webViewRef = ref}
// source={{ uri: url }}
source={{ html }}
javaScriptEnabled
useWebKit
allowFileAccess
startInLoadingState
onLoadStart={this.onLoadStart}
onError={this.onError}
onLoad={this.onLoad}
onLoadEnd={this.onLoadEnd}
renderLoading={this.renderLoading}
renderError={this.renderError}
javaScriptCanOpenWindowsAutomatically
onMessage={this.handleMessage}
injectedJavaScript={`(function() {window.postMessage = function(data) {window.ReactNativeWebView.postMessage(data)}})();`}
/>
</SafeAreaView>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#F5FCFF',
},
})
const html = `
<!DOCTYPE html>
<html lang="en">
<head>
<title>測試頁面</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div style="text-align: center">
<button id="viewPicture">1,viewPicture</button>
<p style="text-align: center">receive react native data: <span id="data"></span></p>
</div>
<script>
window.onload = function () {
/* 監(jiān)聽rn消息
------------------------------------------------------------------------------------------------------------- */
const eventListener = nativeEvent => {
const {actionType, extra} = nativeEvent.data && JSON.parse(nativeEvent.data) || {}
}
//安卓用document,ios用window
window.addEventListener('message', eventListener);
document.addEventListener('message', eventListener);
/* 發(fā)消息給rn
------------------------------------------------------------------------------------------------------------- */
// 1、查看大圖
document.getElementById('viewPicture').onclick = function () {
const action = {
actionType: 'viewPicture',
extra: {
pics: ['https://tva1.sinaimg.cn/large/e6c9d24ely1h0svk2jlcej20ps11ewld.jpg'],
defaultIndex: 0,
},
}
window.postMessage(JSON.stringify(action));
}
}
</script>
</body>
</html>
`到此這篇關(guān)于React Native中WebView與html雙向通信遇到的坑的文章就介紹到這了,更多相關(guān)React WebView與html雙向通信內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
React中實(shí)現(xiàn)編輯框自動(dòng)獲取焦點(diǎn)與失焦更新功能
在React應(yīng)用中,編輯框的焦點(diǎn)控制和數(shù)據(jù)回填是一個(gè)常見需求,本文將介紹如何使用useRef和useEffect鉤子,在組件中實(shí)現(xiàn)輸入框自動(dòng)獲取焦點(diǎn)及失焦后更新數(shù)據(jù)的功能,文中通過代碼示例給大家講解的非常詳細(xì),需要的朋友可以參考下2024-01-01
react 原生實(shí)現(xiàn)頭像滾動(dòng)播放的示例
這篇文章主要介紹了react 原生實(shí)現(xiàn)頭像滾動(dòng)播放的示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04
React Native中實(shí)現(xiàn)動(dòng)態(tài)導(dǎo)入的示例代碼
隨著業(yè)務(wù)的發(fā)展,每一個(gè) React Native 應(yīng)用的代碼數(shù)量都在不斷增加。作為一個(gè)前端想到的方案自然就是動(dòng)態(tài)導(dǎo)入(Dynamic import)了,本文介紹了React Native中實(shí)現(xiàn)動(dòng)態(tài)導(dǎo)入的示例代碼,需要的可以參考一下2022-06-06
React性能優(yōu)化系列之減少props改變的實(shí)現(xiàn)方法
這篇文章主要介紹了React性能優(yōu)化系列之減少props改變的實(shí)現(xiàn)方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-01-01
react-native android狀態(tài)欄的實(shí)現(xiàn)
這篇文章主要介紹了react-native android狀態(tài)欄的實(shí)現(xiàn),使?fàn)顟B(tài)欄顏色與App顏色一致,使用戶界面更加整體。小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-06-06
React?Hook中的useState函數(shù)的詳細(xì)解析
Hook 就是 JavaScript 函數(shù),這個(gè)函數(shù)可以幫助你鉤入(hook into) React State以及生命周期等特性,這篇文章主要介紹了React?Hook?useState函數(shù)的詳細(xì)解析的相關(guān)資料,需要的朋友可以參考下2022-10-10
React+Antd 實(shí)現(xiàn)可增刪改表格的示例
這篇文章主要介紹了React+Antd實(shí)現(xiàn)可增刪改表格的示例,幫助大家更好的理解和學(xué)習(xí)使用React,感興趣的朋友可以了解下2021-04-04

