React Native与webview通信,如何从RN调用react函数?
React Native and webview communication, how to call react function from RN?
我有 RN <=> Webview 运行
- webview 订阅'getFoo' 消息
- webview 将 foo 值设置为 'woo'(使用断点我可以确认 foo 值已更新)
- RN 向 webview 发送 'getFoo' 消息:给我 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>
)
}
useEffect 不会更新,因为您传递的是一个空数组。只需传递状态 foo
然后你就会得到更新:
useEffect(() => {
EventEmitter.subscribe("getFoo", event => {
sendFoo()
})
}, ['foo']) // re-run useEffect on 'foo' state change
我有 RN <=> Webview 运行
- webview 订阅'getFoo' 消息
- webview 将 foo 值设置为 'woo'(使用断点我可以确认 foo 值已更新)
- RN 向 webview 发送 'getFoo' 消息:给我 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>
)
}
useEffect 不会更新,因为您传递的是一个空数组。只需传递状态 foo
然后你就会得到更新:
useEffect(() => {
EventEmitter.subscribe("getFoo", event => {
sendFoo()
})
}, ['foo']) // re-run useEffect on 'foo' state change