Реакция Native и общение через веб-интерфейс, как вызвать функцию реагирования из RN? - PullRequest
0 голосов
/ 28 марта 2020

У меня RN <=> Webview работает

  • webview подписывается на сообщение 'getFoo'
  • webview устанавливает значение foo в 'woo' (с точкой останова я могу подтвердить, что значение foo имеет обновлено)
  • RN отправляет сообщение 'getFoo' в webview: дайте мне значение foo
  • webview получает уведомление о запросе RN посредством обратного вызова, здесь значение foo пусто! почему?
  • webview отправляет значение foo (пустое) в RN

Ниже приведена часть webview

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>
  )
}

Ниже приведена часть RN

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 Ответ

0 голосов
/ 28 марта 2020

useEffect не будет обновляться, поскольку вы передаете пустой массив. Просто передайте состояние foo, и тогда вы получите обновление:

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