【问题标题】:event.preventDefault in React gives TypeError: event is undefinedReact 中的 event.preventDefault 给出 TypeError: event is undefined
【发布时间】:2020-05-12 23:30:30
【问题描述】:

我有一个名为 App 的 React 组件,它应该显示基于 HTML 表单的内容。每次用户提交表单时,App 的状态都应该适应。起初我是这样实现我的课程的:

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {technologies: [], subject: ''};
    this.updateSubject = this.updateSubject.bind(this);
    this.updateTimeline = this.updateTimeline.bind(this);
  }

  componentDidMount() {
    this.updateTimeline();
  }

  updateSubject(event) {
    this.setState({subject: event.target.value});
  }

  updateTimeline() {
    fetch('/timeline?subject=' + this.state.subject)
      .then(res => res.json())
      .then(technologies => this.setState({technologies: technologies}));
  }

  render() {
    return <div>
      <form id="subject" onSubmit={this.updateTimeline}>
        <label>
          Subject:
          <input type="text" value={this.state.subject} onChange={this.updateSubject} />
        </label>
        <input type="submit" value="Submit" />
      </form>
      <Timeline techs={this.state.technologies} />
    </div>;
  }
}

但是,我发现这样每次表单提交都会重新加载页面(或至少调用 App 构造函数)......这是不幸的,因为 App 的状态被重置为空字符串(参见构造函数的第二行)。所以我尝试在updateTimeline方法中添加一个event参数,并在调用fetch之前调用event.preventDefault();

updateTimeline(event) {
  event.preventDefault();
  fetch('/timeline?subject=' + this.state.subject)
    .then(res => res.json())
    .then(technologies => this.setState({technologies: technologies}));
}

这给了我在控制台中的TypeError: event is undefined。为什么会这样?

【问题讨论】:

  • ?? updateTimeline()的定义中没有event参数
  • 那是因为在 componentDidMount 中你调用它时没有传递任何东西。
  • 正如我的问题中所指定的,我当然尝试将event 参数添加到updateTimeline 的签名中。我的问题是,即使在添加了 event 参数之后,我也会得到 TypeError: event is undefined。我可以通过编辑来澄清我的问题。

标签: javascript reactjs forms


【解决方案1】:

onSubmit 非常有棱角,不要那样做,而是像这样更改代码:


class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {technologies: [], subject: ''};
    this.updateSubject = this.updateSubject.bind(this);
    this.updateTimeline = this.updateTimeline.bind(this);
  }

  componentDidMount() {
    this.updateTimeline();
  }

  updateSubject(event) {
    this.setState({subject: event.target.value});
  }

  updateTimeline() {
    return fetch('/timeline?subject=' + this.state.subject)
      .then(res => res.json())
      .then(technologies => this.setState({technologies: technologies}));
  }

  render() {
    return <div>
      <form id="subject">
        <label>
          Subject:
          <input type="text" value={this.state.subject} onChange={this.updateSubject} />
        </label>
        <button type="button" onClick={this.updateTimeline}>Submit</button>
      </form>
      <Timeline techs={this.state.technologies} />
    </div>;
  }
}

【讨论】:

  • 您的解决方案确实很好用。谢谢!但是你是否也知道为什么event.preventDefault(); 在我原来的解决方案中会出错?
  • onSubmit 事件没有获取参数,照你的做,只是 console.log 事件,你会看到一个 undefined
  • 但 React 文档在此链接的 NameForm 示例组件的 handleSubmit 方法中使用了一个事件参数:reactjs.org/docs/forms.html#controlled-components
  • 是的,我知道,但是如果你运行他们自己的 codepen 示例,你会看到同样的错误:TypeError: n is null everypage-1833776b2c0be7ae3094.js:1:327655 onSuccess https://static.codepen.io/assets/packs/js/everypage-1833776b2c0be7ae3094.js:1 N https://static.codepen.io/assets/packs/js/everypage-1833776b2c0be7ae3094.js:1 errorWrapper https://static.codepen.io/assets/packs/js/vendor-0eeab0dfbd1d48f30824.chunk.js:26 onerror https://static.codepen.io/assets/packs/js/vendor-0eeab0dfbd1d48f30824.chunk.js:26
【解决方案2】:

除了我接受的@Ernesto 的答案之外,我还找到了一种更通用(也更语义化?)的方法来获得我想要的行为。这仅涉及从我原来的问题中的代码更改updateTimeline 方法:

updateTimeline(event) {
  if (arguments.length > 0) event.preventDefault();
  fetch('/timeline?subject=' + this.state.subject)
    .then(res => res.json())
    .then(technologies => this.setState({technologies: technologies}));
  }

...这允许保留&lt;input type="submit" value="Submit" /&gt; 标签,这对我来说听起来比button 标签更具语义。同时,这也很好地处理了用户点击返回而不是点击“提交”的事件。

【讨论】:

    猜你喜欢
    • 2018-05-17
    • 2020-06-05
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-24
    • 2015-05-04
    相关资源
    最近更新 更多