我正在尝试将数据从 native iOS应用程序传输到在UIWebView中运行的React(不是react-native)Web应用程序。
我从本地viewcontroller得到一个字符串,需要将其“注入(inject)”到React组件类中的<input>
元素的值中。我给元素一个id
像这样:
render() {
<div>
...
<input id="iccid" type="text" name="iccid" pattern="\d*" onChange={this.iccidChanged.bind(this)} autoFocus />
...
</div>
}
然后从iOS使用JavaScriptCore(Swift代码)运行:
self.context = self.webView.valueForKeyPath("documentView.webView.mainFrame.javaScriptContext") as? JSContext
self.context!.evaluateScript("document.getElementById('iccid').value='\(barcodeValue)';")
这似乎工作正常,我可以在webview内的DOM中看到更新的值,问题是我的React
onChange
函数(用于验证值并更改组件状态)未触发,因为React不会将其解释为更改(可能是因为DOM与虚拟DOM处理的对比)。什么是从iOS更新元素值并让React组件表现出与用户键入内容相同的正确方法/最佳实践?
最佳答案
我假设您要在扫描条形码时触发事件。您的iOS应用可能不需要知道应该将事件分派(dispatch)到哪里(即哪个输入字段以及如何输入)。仅要向Web View 发出已扫描条形码的信号就足够了。
您可以将自定义DOM事件调度到window
,并让一些React组件监听该事件。
window.dispatchEvent(new CustomEvent('barcodescan', {
detail: {
value: '(barcodeValue)'
}
}))
然后,您可以创建一个非渲染组件,该组件将监听条形码事件:
const BarcodeListener = React.createClass({
propTypes: {
onBarcodeScan: React.PropTypes.func.isRequired
},
componentDidMount () {
window.addEventListener('barcodescan', this.handleBarcodeScan)
},
componentWillUnmount () {
window.removeEventListener('barcodescan', this.handleBarcodeScan)
},
render () {
return null
},
handleBarcodeScan (e) {
this.props.onBarcodeScan(e)
}
})
然后,在您的表单中,您可以将输入与条形码事件监听器一起呈现:
render () {
return (
<div>
...
<input ... />
<BarcodeListener onBarcodeScan={this.handleBarcodeScan} />
</div>
)
}
然后分别处理条形码扫描事件。
关于javascript - 从iOS UIWebView更新React组件中元素的值,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34080370/