rn登录后得到的token需要传递给网页,js获取到的浏览器信息需要传递给rn
RN Index.js:
import React from 'react'
import { WebView } from 'react-native-webview'
import useList from './useList'
export default function Index(props) {
const { uri, jsCode, webViewRef, handleMessage, handleLoad } = useList(props)
return (
<>
<WebView
ref={webViewRef}
source={{
uri,
}}
style={{ flex: 1 }}
injectedJavaScriptBeforeContentLoaded={jsCode} //injectedJavaScriptBeforeContentLoaded injectedJavaScript
originWhitelist={['*']}
onMessage={(value) => handleMessage(value)}
onLoad={() => handleLoad()}
/>
</>
)
}
RN useList.js:
import { useState, useEffect, useRef } from 'react'
import AsyncStorage from '@react-native-async-storage/async-storage'
import Constants from 'expo-constants'
export default function useList() {
let uri =
Constants.manifest.extra.REACT_APP_MODE === 'dev'
? `${Constants.manifest.extra.devHost}:3000/#/single/demo/test1`
: 'https://chat.xutongbao.top/#/ai/chat'
const webViewRef = useRef(null)
const jsCode = `
window.reactNative = {};
window.reactNative.testData = 'inject data:1';
true; // note: this is required, or you'll sometimes get silent failures
`
const handleLoad = async () => {
console.log('load')
}
const handleMessage = (value) => {
let payload = value.nativeEvent?.data
? JSON.parse(value.nativeEvent.data)
: {}
let type = payload.type
if (type === 'getToken') {
let fun = async () => {
const token = await AsyncStorage.getItem('token')
webViewRef.current.postMessage(
JSON.stringify({
type,
token: token,
})
)
}
fun()
webViewRef.current.postMessage(
JSON.stringify({
type: 'getBrowserInfo',
})
)
} else if (type === 'getBrowserInfo') {
console.log(payload)
}
}
useEffect(() => {
// eslint-disable-next-line
}, [])
return {
uri,
jsCode,
webViewRef,
handleMessage,
handleLoad,
}
}
网页 Index.js:
import React, { useState, useEffect } from 'react'
import uaParser from 'ua-parser-js'
import './index.css'
export default function Index() {
const [testData, setTestData] = useState()
const [token, setToken] = useState()
const handleGetDataFromInjected = () => {
if (window.reactNative?.testData) {
setTestData(window.reactNative?.testData)
setToken(window.reactNative?.token)
}
}
const handleGetToken = () => {
window.ReactNativeWebView.postMessage(JSON.stringify({ type: 'getToken' }))
}
const handleMessage = () => {
window.document.addEventListener('message', function (e) {
let payload = e.data ? JSON.parse(e.data) : {}
let type = payload.type
if (type === 'getToken') {
setToken(payload.token)
} else if (type === 'getBrowserInfo') {
let ua = uaParser(navigator.userAgent)
const { browser } = ua
window.ReactNativeWebView.postMessage(JSON.stringify({ type, browser }))
}
})
}
useEffect(() => {
handleGetDataFromInjected()
}, [])
useEffect(() => {
handleGetToken()
}, [])
useEffect(() => {
handleMessage()
}, [])
return (
<div className='m-test1'>
<div>{testData}</div>
<div>token:{token}</div>
</div>
)
}
参考链接:
https://github.com/react-native-webview/react-native-webview/blob/eb2ce07e728352abe8b11d10a9de2a4fdc2f228b/docs/Guide.md#communicating-between-js-and-native
https://chat.xutongbao.top/