React防止在输入框内按下回车键提交表单

70

当按下回车键时,React 如何防止表单提交

我有一个 React 搜索栏组件,父容器可以使用以下方式调用:

<SearchBar onInputChange={this.handleInputChange} />

每次用户更改输入时,父容器将收到通知。这就是为什么我的搜索栏不需要任何提交按钮。

然而,我发现如果我在搜索栏内按下回车键,整个页面都会刷新。而我不想要那样。

我知道如果在表单中有一个按钮,我可以调用 event.preventDefault() 方法。但在这种情况下,我没有按钮,所以我不知道该怎么做。

class SearchBar extends Component {
    constructor(props) {
        super(props);
        this.state = { value: '' };
        this.handleChange = this.handleChange.bind(this)
    }

    handleChange(e) {
        this.setState({ value: e.target.value });
        this.props.onInputChange(e.target.value);
    }

    render() {
        return (
        <div id="search-bar">
            <form>
            <FormGroup controlId="formBasicText">
                <FormControl
                type="text"
                onChange={this.handleChange}
                value={this.state.value}
                placeholder="Enter Character Name"
                />          
            </FormGroup>
            </form>
        </div>
        );
    }
}

export default SearchBar

2
你需要使用表单标签的原因是什么?如果你将它替换为 div 标签,那么回车键就不会提交了。 - sissonb
Div也可以,但我放了一个表单以防将来需要添加更多字段,表单可以提供更多控制。 - ErnieKev
6个回答

100

您需要创建一个表单处理程序,以防止默认的表单操作。

最简单的实现方式如下:

<form onSubmit={e => { e.preventDefault(); }}>

但是理想情况下,您应该为此创建一个专门的处理程序:

<form onSubmit={this.submitHandler}>

使用以下实现方式:

submitHandler(e) {
    e.preventDefault();
}

1
第二种形式更适合提高可读性吗?还是有其他原因? - Troy Cosentino
5
其他原因:在第一个 e => { e.preventDefault(); } 中,这是一个匿名函数,在每个渲染循环中被重新创建,因此 React 会替换子元素中的该函数。使用专用的处理程序,函数实例只会被创建一次,然后保持不变。 - zerkms
1
对我没用。有效的方法是在<form>上使用onKeyPress={(e) => { e.key === 'Enter' && e.preventDefault(); }} - Avi Kaminetzky
@AviKaminetzky,e.key === 'Enter'条件不可能改变任何行为。很可能你在其他方面有问题。此外,我不明白onKeyPress对于表单有什么意义。 - zerkms

43

在一个包含搜索输入字段的React组件中,嵌套在更大的(非React或React)表单中,这是我在各种浏览器中使用最佳的方法:

<MyInputWidget
  label="Find"
  placeholder="Search..."
  onChange={this.search}
  onKeyPress={(e) => { e.key === 'Enter' && e.preventDefault(); }}
  value={this.state.searchText} />

(e)=>{e.key === 'Enter'} (@DavidKamer的回答) 是错误的: 你不需要 event.target. 这是输入框。你需要事件本身。在React中 (特别是目前的16.8版本),你需要使用 event.key (比如 e.key 或者其他你想要的名字)。


2
keypress已被弃用 https://developer.cdn.mozilla.net/en-US/docs/Web/API/Element/keypress_event - rofrol
5
React 17.0.1版本的键盘事件列表包括:onKeyDown、onKeyPress和onKeyUp。请参见https://reactjs.org/docs/events.html#keyboard-events。我不知道它们是否被填充到不再使用的内容中,我没有细查。但是在大多数情况下,onKeyDown或onKeyUp应该可以正常工作,就像上面的例子一样。--谢谢 - eon

13

我不确定这个方法是否适用于所有情况,因为当你在表单的输入字段中按下回车键时,仍然会触发onSubmit方法,尽管默认提交不会发生。这意味着您仍将触发您为表单设计的伪提交操作。以下是一个使用ES6解决该问题的一行代码:

<input onKeyPress={(e)=>{e.target.keyCode === 13 && e.preventDefault();}} />

这个解决方案应该没有副作用,可以直接解决问题。


如果只有一个输入,这是一个不错的解决方案,但对于具有多个控件的表单,在onSubmit级别处理它会更好。 - Andrew Boyd
6
我的解决方案可以在许多可能会导致此问题的情况下运作良好。许多人会尝试上述解决方案,但发现它会防止表单的每个部分都能使用回车键。在需要让默认功能继续正常工作的情况下,更具体的解决方法更好。如果你的表单中有一个单独的输入或组件,你不希望它触发提交函数,那么这是唯一可行的解决方案。其他方法将明确禁用回车按钮或明确使用HTML5标准禁用提交,但不会实现所要求的功能。 - David Kamer
1
谢谢。禁用多个输入中的单个输入正是我要做的。 - NateQ
2
对我来说,e.target.keyCode 返回未定义,但 e.key === 'Enter' 很好用。 - ORunnals
keypress已过时。 - rofrol
e.code === "Enter" if you don't care about IE - Yunhai

13

防止用户键入回车的最佳方法,如Eon所建议的那样,是将以下内容添加到您的输入元素中

onKeyPress={(e) => { e.key === 'Enter' && e.preventDefault(); }}

2
keypress已被弃用 https://developer.cdn.mozilla.net/en-US/docs/Web/API/Element/keypress_event - rofrol

7
这对我有效:
<Input
   ...
   onKeyDown={(e) => { e.key === 'Enter' && e.preventDefault() }}
/>

0

防止按下回车键进行搜索输入:

<input type="text" onKeyPress={e => {
  if (e.key === 'Enter') e.preventDefault();
}} />

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