網(wǎng)站首頁 編程語言 正文
安卓、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>
`
原文鏈接:https://blog.csdn.net/liuxingyuzaixian/article/details/125199131
相關(guān)推薦
- 2022-07-17 SQL?Server中使用表變量和臨時表_MsSql
- 2022-07-20 React使用有限狀態(tài)機(jī)的實(shí)現(xiàn)示例_React
- 2022-04-27 C語言的常量,字符串,轉(zhuǎn)義字符,注釋你都了解嗎_C 語言
- 2022-06-18 kubernetes(k8s)安裝metrics-server實(shí)現(xiàn)資源使用情況監(jiān)控方式詳解_云其它
- 2022-11-10 C語言strlen函數(shù)全方位講解_C 語言
- 2022-03-15 使用axios出現(xiàn)跨域問題Response to preflight request doesn‘t
- 2022-12-07 C語言中的數(shù)據(jù)整除判斷問題_C 語言
- 2023-04-08 C#中{get;set;}的具體使用_C#教程
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支