以编程方式填充ReactJS输入的正确方法

时间:2017-11-21 11:36:58

标签: javascript jquery reactjs

我正在构建一个运行JavaFX Webkit的无头爬虫,它肯定不如chrome的v8强大。

但是我最近遇到了问题,我正在尝试输入一个值来对渲染的输入字段做出反应。

这是我到目前为止所做的并且失败了。[注意:我无法控制源/ React代码。由于我正在尝试抓取目标网站]

  1. jQuery - $('input.r_input').val("2");
  2. Vanila JS - document.querySelector("input.r_input").value = "2";
  3. 通过jquery触发器触发更改事件 - 更改,模糊,键盘,键盘等。
  4. 创建手动事件,如:

    event = new Event( event, {target: obj, bubbles: true} ); event.simulated = true; return obj ? obj.dispatchEvent(event) : false;

  5. 并触发input事件。

    以上都不起作用。

    如果可能有助于添加更多上下文,我会在网站上的JS文件中添加部分反应代码。

    创建:

    t.prototype.createInputProps = function(e) {
        return {
            disabled: this.props.submitting || e > this.focusIndex,
            className: "r_input",
            type: "tel",
            name: "tan-" + e,
            maxLength: 1,
            pattern: "[\\d]*",
            tabIndex: 0,
            placeholder: "·",
            autoComplete: "off"
        }
    }
    

    渲染:

    t.prototype.render = function() {
        var e = this.props,
            t = e.meta,
            n = t.touched,
            r = t.error,
            o = (e.input.value, sa()("r_input", {
                "has-error": r && n
            }));
        return us("article", {
            className: o
        }, void 0, us("div", {
            className: "r_inputs"
        }, void 0, ro.a.createElement("input", as({
            onPaste: this.handleOnPaste,
            ref: this.addInputToList,
            onKeyUp: this.handleKeyUp,
            value: this.getValue(0)
        }, this.createInputProps(0))), ro.a.createElement("input", as({
            ref: this.addInputToList,
            onKeyUp: this.handleKeyUp,
            value: this.getValue(1)
        }, this.createInputProps(1))), ro.a.createElement("input", as({
            ref: this.addInputToList,
            onKeyUp: this.handleKeyUp,
            value: this.getValue(2)
        }, this.createInputProps(2))), ro.a.createElement("input", as({
            ref: this.addInputToList,
            onKeyUp: this.handleKeyUp,
            value: this.getValue(3)
        }, this.createInputProps(3))), ro.a.createElement("input", as({
            ref: this.addInputToList,
            onKeyUp: this.handleKeyUp,
            value: this.getValue(4)
        }, this.createInputProps(4))), ro.a.createElement("input", as({
            ref: this.addInputToList,
            onKeyUp: this.handleKeyUp,
            value: this.getValue(5)
        }, this.createInputProps(5)))), n && r && us(is.a, {}, void 0, r))
    }
    

    不确定我是否需要添加handleKeyUp,但其中包含一些验证码。

    任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:1)

在您的情况下,看起来您可以在更改值后在元素上触发keyup事件。您可能还必须根据React状态更改等待元素出现在DOM中。试试这个

setTimeout(function() {
    var event = new Event('keyup', { bubbles: true });
    $('input.r_input').val("2")[0].dispatchEvent(event);
}, 3000);

如果无法访问相关网页,当然很难提供明确的内容。

注意:我想出伏都教通过this thread发送keyup事件,该事件表示React onChange处理程序侦听input事件并查看代码您提供了哪些电话onKeyUp。我的示例代码在React& amp;中使用了onChange处理程序。调度链接线程中规定的input事件。

另请注意:我无法使用jQuery的trigger方法,也许您可​​以弄清楚我在那里缺少的内容,但使用本机Javascript的事件调度正在下面的代码段中工作。

继续阅读以获取详细信息!

您的问题没有单一的答案,因为给定的React组件从input字段读取值的方式可能会有所不同,因此您需要查看您尝试操作的每个React实现。我猜测onChange是React在文本字段中捕获输入的最常用方法。 The React onChange handler listens for input events

jQuery's .ready() callback触发后,React的状态也可能会更新,导致您要查找的元素被添加到DOM中。这意味着你的选择器没有找到任何东西,因为他们正在寻找的元素在他们看的时候不存在于DOM中。 (这就是我在建议的解决方案中添加setTimeout)的原因。

这里我说明了在React状态更改后出现在DOM中的元素的问题,以及一个工作示例,其中jQuery用于设置由React管理的input元素的值。 (确保在运行它时查看控制台输出以了解正在发生的事情),当HTML全部完成时,您应该在HTML中看到它

  

React认为该值为50

jQuery(function() {
  console.log('jquery loaded');
  
  function searchForNodeOfInterest() {
    console.log('jQuery searching for nodes of interest');
    if(jQuery('#interesting-node').length === 0) {
      console.log('jQuery did not find the selector of interest');
    } else {
      console.log('jQuery found the selector of interest, setting input value...');
      var event = new Event('input', { bubbles: true });
      jQuery('#interesting-node').val(50)[0].dispatchEvent(event);
    }
  }
  
  searchForNodeOfInterest();
  
  setTimeout(searchForNodeOfInterest, 4000);
  console.log('jQuery - taking a nap, I will search again soon...');
});

var App = React.createClass({
  getInitialState: function() {
      return {
        hidden: true
      };
  },
  componentDidMount: function() {
    console.log('react mounted');
  },
  // Imagine something happens inside react (AJAX response comes in for example),
  // causing the nodes of interest to be rendered in DOM
  componentWillMount: function() {
    var that = this;
    setTimeout(function() {
      console.log('react updating the state...');
        that.setState({
          hidden: false,
          value: null
        })
    }, 2000);
  },
  handleInput: function(e) {
    console.log('react handling input...', e.target.value);
    this.setState({
      value: e.target.value
    })
  },
  render: function() {
    return this.state.hidden ? null : <form>React Powered Input: <input type="text" id="interesting-node" onChange={this.handleInput}/><p>React thinks the value is {this.state.value}</p></form>
  }
});


ReactDOM.render(<App />, document.getElementById('react'));
<body>
  <div id="react"></div>
</body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

在一段随机时间内,比setTimeout更可靠的技术是一个包装器,它定期检查是否存在选择器like this

答案 1 :(得分:0)

我可以想象你根本无法做到。 这取决于它是如何实现的以及它正在监听的事件。

如果控制React组件并注册&#39; onChange&#39;事件,那么它可能是可能的。

如果它是不受控制的组件,那么我猜它可能不起作用。 即使你以某种方式填写输入。在表单提交时,它可能仍在使用其内部状态的值。

https://reactjs.org/docs/uncontrolled-components.html

https://reactjs.org/docs/forms.html#controlled-components

答案 2 :(得分:0)

首先验证该元素是否存在香草if。如果它存在,那么以编程方式填充它。请注意,某些UI库可能需要在动态添加值时进行初始化或升级。

if(document.getElementById("my-input")){
  document.getElementById("my-input").value = "foo";
}

如果您使用脚本添加元素,则可能需要在创建元素后附加事件侦听器。