【问题标题】:Update value of an element in React component from iOS UIWebView从 iOS UIWebView 更新 React 组件中元素的值
【发布时间】:2016-03-08 21:58:15
【问题描述】:

我正在尝试将数据从原生 iOS 应用程序传输到在 UIWebView 中运行的 React(不是 react-native)网络应用程序。

我从原生 viewcontroller 得到一个字符串,需要将它“注入”到 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 组件表现得像用户输入它的正确方法/最佳实践是什么?

【问题讨论】:

    标签: javascript ios swift uiwebview reactjs


    【解决方案1】:

    我假设您想在扫描条形码时触发一个事件。您的 iOS 应用可能不需要知道应该在何处分派事件(即哪个输入字段以及如何分派)。只需向 Web 视图发出条形码已被扫描的信号就足够了。

    您可以将自定义 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>
        )
      }
    

    然后单独处理条码扫描事件。

    【讨论】:

    • 终于通过使用类似的想法自己解决了这个问题 - 我只是在 DOM 元素本身(不是虚拟的)上添加了事件侦听器,并使用了 swift 代码中的new Event()。无需创建一个虚拟的不可见元素 - 但您的建议也可以。接受为正确答案。
    • 谢谢。我更喜欢虚拟的不可见元素,因为它清晰地分离了关注点并允许 BarcodeListener 在其他地方重用。在使用过非常大的 React 应用程序后,我了解到单一职责原则是最重要的。当组件做不止一件事时,就很难跟踪其中发生的所有事情。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-11
    • 1970-01-01
    相关资源
    最近更新 更多