react-native-webview RN和html双向通信

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 (
    <>
       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 (
    
{testData}
token:{token}
) }

react-native-webview RN和html双向通信_第1张图片

 react-native-webview RN和html双向通信_第2张图片

 

 

参考链接:

https://github.com/react-native-webview/react-native-webview/blob/eb2ce07e728352abe8b11d10a9de2a4fdc2f228b/docs/Guide.md#communicating-between-js-and-native

https://chat.xutongbao.top/ 

你可能感兴趣的:(web前端,html,前端)