網站首頁 編程語言 正文
安卓、ios原生與html雙向通信相對簡單且成熟,但是React Native與html的雙向通信存在那么一丟丟的坑
一、參數配置
導包
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)}})();`}
相關回調函數
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) || {}
}
二、坑點
react-native-webview使用postMessage后H5不能監聽問題
注意:這里安卓用document,ios用window,否則會出現react-native-webview使用postMessage后H5不能監聽問題
/* 監聽rn消息 */
const eventListener = nativeEvent => {
//解析數據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監聽不到的問題
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監聽不到的問題
三、React Native與html雙向通信
3.1、RN發數據到WebView
RN通過postMessage發送數據
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接受數據
/* 監聽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發數據到RN
WebView通過postMessage發送數據
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 () {
/* 監聽rn消息
------------------------------------------------------------------------------------------------------------- */
const eventListener = nativeEvent => {
const {actionType, extra} = nativeEvent.data && JSON.parse(nativeEvent.data) || {}
}
//安卓用document,ios用window
window.addEventListener('message', eventListener);
document.addEventListener('message', eventListener);
/* 發消息給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>
`
原文鏈接:https://blog.csdn.net/liuxingyuzaixian/article/details/125199131
相關推薦
- 2022-10-17 Kotlin編程基礎數據類型示例詳解_Android
- 2022-04-09 詳解Docker下nginx外掛配置和文件_docker
- 2022-10-26 Python如何用NumPy讀取和保存點云數據_python
- 2022-10-22 Kotlin淺析null操作方法_Android
- 2022-06-13 Docker容器數據卷介紹及操作示例_docker
- 2022-06-08 ASP.NET?Core使用IHttpClientFactory發出HTTP請求_基礎應用
- 2022-04-17 IDEA下載源文件,報找不到
- 2022-05-13 python實現圖書館借閱系統_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支