我正在尝试将数据从 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/

10-11 22:40
查看更多