如何在我的序列化React`Field`组件数据中显示浏览器自动填充值?

时间:2014-05-02 16:13:43

标签: javascript forms autofill reactjs

我在React中构建了一个Form组件,此表单中包含一些Field组件作为子组件。我正在使用这些组件来构建具有电子邮件地址和密码的登录表单。我的表单有一个onSubmit处理程序,用于序列化其子项(Field)并发送一个AJAX请求。

在正常情况下,一切都运作良好。但是,当浏览器像Chrome Autofill这样的表单中包含我的电子邮件地址和密码时,序列化并不会提取输入的值。

Field目前看起来像这样:

/** @jsx React.DOM */

var Field = React.createClass({
  serialize: function() {
    return { name: this.props.name, value: this.refs.field.state.value };
  },

  render: function() {
    return (
      <div>
        <label>
          {this.props.label}
          <input type={this.props.type} ref="field"
            name={this.props.name}
            defaultValue={this.props.value} />
        </label>
      </div>
    )
  }
});

如何让浏览器自动填充值显示在序列化的Field数据中?

3 个答案:

答案 0 :(得分:3)

状态应从一个方向流动,从顶层向下流动。因此,进入子元素以获得其状态是一个坏主意。要使用此结构完成序列化,您只需要访问DOM以获取输入的值。在上面的代码示例中,serialize方法应为:

serialize: function() {
  return { name: this.props.name, value: this.refs.field.getDOMNode().value };
},

答案 1 :(得分:0)

这是我使用refs :)的解决方案..基本上我在第一秒手动触发更改事件。背后的原因是每个浏览器都以不同的方式处理自动填充,并且这会根据浏览器版本而变化。现在无法正确覆盖这个

  componentDidMount () {
    let tries = 4;
    this.int  = setInterval(() => {
      tries--;
      if (tries === 0) {
        this._createChangeEvent();
        clearInterval(this.int);
      }
    }, 300);
  }

  _createChangeEvent = () => {
    if ("createEvent" in document) {
      const evt = document.createEvent("HTMLEvents");
      evt.initEvent("change", false, true);
      this.input.dispatchEvent(evt);
    } else {
      this.input.fireEvent("onchange");
    }
  };

答案 2 :(得分:0)

使用onChange事件是更新绑定到组件的任何模型属性的最常见方案,但是当浏览器“自动填充”表单时,您还可以使用onBlur来捕获值。

var Input = React.createClass({
  getInitialState: function() {
    return {typed: ''};
  },
  onBlur: function(event) {
    this.setState({typed: event.target.value});
  },
  render: function() {
    return <div>
        <input type="text" onBlur={this.onBlur.bind(this)}/>
        You typed: <code>{this.state.typed}</code>
      </div>
  }
});