React表单组件的onSubmit处理程序无法工作

26

我有以下的React组件:

class Form extends React.Component {
  handleSubmit(e) {
    e.preventDefault();

    let loginInput = ReactDOM.findDOMNode(this.refs.login);

    // change Main component's state
    this.props.addCard(loginInput.value);

    // reset the form
    loginInput.value = '';
  }

  render() {
    return(
      <form onSubmit={this.handleSubmit}>
        <input placeholder="githug login" ref="login" />
        <button>Add Login</button>
      </form>
    );
  }
}

正如您所看到的,我希望每当表单被提交时都会调用handleSubmit函数。 我通过将该函数添加到onSubmit处理程序中来表示这一点。

该函数在正确的时间被调用。 但是,在该函数内部,this的值为null。 这让我感到惊讶,因为我期望this的值是React组件。 this为null的事实让我感到惊讶,因为我正在使用与官方React文档建议的非常相似的逻辑/代码。

我希望能得到帮助,找出为什么this不是预期的React组件,以及如何修复代码使其正常工作。


1
http://www.newmediacampaigns.com/blog/refactoring-react-components-to-es6-classes --- 查看步骤#3或https://facebook.github.io/react/blog/2015/01/27/react-v0.13.0-beta-1.html#autobinding 或http://egorsmirnov.me/2015/08/16/react-and-es6-part3.html - zerkms
7个回答

25

当你使用 ReactES2015 类 时,应该将 this 设置为事件处理程序。

class Form extends React.Component {
  constructor(props) {
     super(props);
     this.handleSubmit = this.handleSubmit.bind(this);
  }    

  handleSubmit(e) {
    e.preventDefault();

    let loginInput = this.refs.login;
    this.props.addCard(loginInput.value);
    loginInput.value = '';
  }

  render() {
    return(
      <form onSubmit={ this.handleSubmit }>
        <input placeholder="githug login" ref="login" />
        <button>Add Login</button>
      </form>
    );
  }
}

示例

无自动绑定

方法遵循普通的ES6类语义,这意味着它们不会自动将this绑定到实例上。您必须显式地使用.bind(this)或箭头函数=>。


1
对我来说,这是一个绑定问题:this.handleSubmit = this.handleSubmit.bind(this); - kmithi1
如果您使用钩子,这将不是一个问题 ( ͡° ͜ʖ ͡°) - Adam Fowler

22

您需要使用 button 或带有 type="submit"input

<button type="submit">Submit</button>

或者

<input type="submit" value="Submit" />

6
额外信息:以编程方式提交表单未调用“onSubmit”回调函数。 添加一个带有“type = submit”的按钮可以解决该问题。 - Bernat
1
是的,那就是HTML5表单的行为。 - ma_dev_15

11

一个显而易见的信息是:不要忘记将按钮放在<form>标签内。

我曾经陷入困境,直到我意识到我把提交按钮放在了表单外面,像这样:

  <form onSubmit={ this.handleSubmit }>
    <input placeholder="githug login" ref="login" />
  </form>            
  <button type="submit">Add Login</button>
因此,onSubmit事件未被调用,而且永远不会被调用。

5

对我来说,是因为该表单未设置action属性。

<form onSubmit={this.handleSubmit} action="#">
    <input placeholder="githug login" ref="login" />
    <button>Add Login</button>
</form>

1
这种情况曾经发生在我身上,当时我的提交处理程序只是将一个新的位置推到历史记录中。提交表单会刷新页面,使我停留在旧的位置。我通过在提交处理程序开头加入event.preventDefault()来解决这个问题。

0
如果您正在使用函数组件,请确保您的按钮类型为“Submit”,而不是“button”。这就是我做错的地方!

0

正如@Bernat在评论中提到的那样。

额外信息:以编程方式提交表单没有调用onSubmit回调函数。添加一个type="submit"button即可解决问题。

这意味着此代码不会触发onSubmit函数:

class Form extends React.Component {

    submitProgrammatically() {
        const element = document.querySelector(`form`);
        element.submit(); // <-- will NOT trigger onSubmit
    }

    render() {
        return(
            <form onSubmit={(e) => {
                e.preventDefault();
            }}>
                <input placeholder="githug login" ref="login" />
                <button type="submit">Add Login</button>
            </form>
        );
    }
}

虽然这段代码会触发 onSubmit

class Form extends React.Component {

    submitProgrammatically() {
        const element = document.querySelector(`form button[type='submit']`);
        element.click(); // <-- will trigger handleSubmit
    }

    render() {
        return(
            <form onSubmit={(e) => {
                e.preventDefault();
            }}>
                <input placeholder="githug login" ref="login" />
                <button type="submit">Add Login</button>
            </form>
        );
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接