问题
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