【问题标题】:form.submit callback not getting invokedform.submit 回调没有被调用
【发布时间】:2019-07-10 20:09:49
【问题描述】:

我在我的一个应用程序中使用 react-bootstrap-typeahead 模块。这工作正常,除了一种情况。

如果没有结果,我无法通过按 ENTER 键提交表单。

即; 如果 react-bootstrap-typeahead 提供了 建议,我可以选择其中一个选项并提交表单。在这种情况下,可以调用回调 onSubmit。

如果 react-bootstrap-typeahead 没有提供建议,则无法提交表单。

如果我使用 form.submit() 方法的 onKeyDown 事件提交表单,表单将被提交,但是页面会刷新而不是调用回调,这导致我无法控制结果。

期望的结果:如果 react-bootstrap-typeahead 提供了建议,即使没有提供建议,我也应该能够调用 onSubmit 回调。

这是我的代码。

<form ref={(form) => this.form = form} onSubmit={this.sendMessage}>
  <Typeahead
    id="rbt-example"
    dropup={true}
    ref={(typeahead) => this.typeahead = typeahead}
    onChange={this.valueChanged}
    onInputChange={this.updateQuery}
    onBlur={(e) => this.updateQuery(e.target.value, e)}
    onKeyDown={(e) => {
      // Submit the form when the user hits enter.
      if (e.keyCode === 13) {
        this.form.submit();
      }
    }}
    options={options}
    placeholder="Type your queries here..."
    renderMenu={(results, menuProps) => {
      // Hide the menu when there are no results.
      if (!results.length) {
        return null;
      }
      return <TypeaheadMenu {...menuProps} options={results} />;
    }}
  />
  <button type="submit">Submit</button>
</form>

【问题讨论】:

    标签: javascript reactjs react-bootstrap-typeahead


    【解决方案1】:

    问题可能是调用this.form.submit(),它处理 DOM 中的表单提交(而不是 React),正如您所说,它使您无法控制。它正在刷新页面,因为您无法控制调用 event.preventDefault() 的事件。

    当用户按下回车键时,您应该调用this.sendMessage,而不是this.form.submit。大概你在sendMessage 中调用event.preventDefault,所以你应该从onKeyDown 传递事件:

    onKeyDown={e => {
      if (e.keyCode === 13) {
        this.sendMessage(e);
      }
    }}
    

    这样,无论是响应用户按下提交按钮还是回车,您都会以相同的方式处理表单提交。

    【讨论】:

    • 感谢您的回答和解释。我通过稍微修改实现了这个答案,这符合我的项目要求。经过一整天的实际数据测试后,我将在这里分享。
    【解决方案2】:

    如果您注意到我的问题中的代码,我正在处理多个事件。尤其是onChangeonKeyDown

    关于react-bootstrap-typeahead,我们需要了解的几件事是

    1. onChange,react-bootstrap-typeahead 会将所选对象传递给回调,而 onKeyDown react-bootstrap-typeahead 将传递事件,我将使用 event.target.value 从中获取值
    2. onChange 只会在onKeyDown 之后触发。因此,如果我们想根据选择的对象做一些操作,而在onKeyDown回调中使用的值将不起作用。

    为了克服这种情况,我使用setTimeout 也删除了表单元素。 所以我的解决方案就变成了

    <Typeahead
        id="rbt-example"
        dropup={true}
        ref={(typeahead) => this.typeahead = typeahead}
        onChange={this.valueChanged}
        onInputChange={this.updateQuery}
        onBlur={(e) => this.updateQuery(e.target.value, e)}
        onKeyDown={(e) => {
          // Submit the form when the user hits enter.
          if (e.keyCode === 13) {
              if (this.timerid) {
                clearTimeout(this.timerid);
              }
              this.timerid = setTimeout(
                () => {
                  this.sendMessage();
                },
                300
              );
          }
        }}
        options={options}
        placeholder="Type your queries here..."
        renderMenu={(results, menuProps) => {
          // Hide the menu when there are no results.
          if (!results.length) {
            return null;
          }
          return <TypeaheadMenu {...menuProps} options={results} />;
        }}
      />
      <button onClick={() => this.sendMessage() }>Send</button>
    

    这样,我调用sendMessage 方法onKeyDown 并单击按钮。我还可以使用选定的选项对象。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-26
      • 2013-04-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多