React Native and webview communication, how to call react function from RN?

耗尽温柔 提交于 2020-04-17 18:30:09

问题


I have RN <=> Webview running

  • webview subscribe to 'getFoo' message
  • webview sets foo value to 'woo' (with breakpoint I can confirm foo value has been updated)
  • RN sends 'getFoo' message to webview : give me the value of foo
  • webview gets notified of the request of the RN via callback, here foo value is empty! why?
  • webview sends the foo value (empty) to RN

Below is the webview part

import _ from "lodash"
import React, {
  useState,
  useContext,
  useEffect,
  useReducer,
  useCallback,
  useRef
} from "react"

const EventEmitter = {
  _events: {},
  dispatch: function(event, data) {
    if (!this._events[event]) return
    this._events[event].forEach(callback => callback(data))
  },
  subscribe: function(event, callback) {
    if (!this._events[event]) this._events[event] = []
    this._events[event].push(callback)
  }
}

window.EventEmitter = EventEmitter

// webview
const WebviewApp = props => {
  // https://codesandbox.io/s/lively-breeze-l9z82

  const [foo, setFoo] = useState('')

  useEffect(() => {


    EventEmitter.subscribe("getFoo", event => {
      sendFoo()
     // here foo is empty! 
    })
  }, [])

  const sendFoo = () => {
    window.ReactNativeWebView.postMessage(foo)
  }

  const handleClick = () => {
    setFoo("woo")
  }

  return (
    <div className="App">
      <button onClick={handleClick} />
    </div>
  )
}

Below is RN part

import {WebView} from 'react-native-webview'

const RNApp = props => {
  const webEl = useRef(null)

  getFooFromWebview = () => {
    const run = `
window.EventEmitter.dispatch('getFoo', {});
`
    webEl.current.injectJavaScript(run)
  }


  const uri = "server url which hosts the webview code"
  return (
    <View style={{flex: 1}}>
      <TouchableOpacity onPress={getFooFromWebview}>
        <Text>click</Text>
      </TouchableOpacity>

      <WebView
        ref={webEl}
        javaScriptEnabledAndroid
        source={{uri}}
        onMessage={(event) => {
          console.log(event)
        }}
        data={props.data}
      />
    </View>
  )

}

回答1:


useEffect will not update since you're passing an empty array. Just pass the state foo and then you'll get update:

useEffect(() => {
    EventEmitter.subscribe("getFoo", event => {
      sendFoo()
    })
  }, ['foo']) // re-run useEffect on 'foo' state change


来源:https://stackoverflow.com/questions/60897735/react-native-and-webview-communication-how-to-call-react-function-from-rn

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!