如何在react.js中使用Enter键提交表单?

197

这是我的表单和 onClick 方法。我希望在按下键盘上的 Enter 按钮时执行此方法。怎么做?

N.B:不使用 jQuery 更好。

comment: function (e) {
  e.preventDefault();
  this.props.comment({
    comment: this.refs.text.getDOMNode().value,
    userPostId:this.refs.userPostId.getDOMNode().value,
  })
},


<form className="commentForm">
  <textarea rows="2" cols="110" placeholder="****Comment Here****" ref="text"  /><br />
  <input type="text" placeholder="userPostId" ref="userPostId" /> <br />
  <button type="button" className="btn btn-success" onClick={this.comment}>Comment</button>
</form>
18个回答

323
将 `

2
为什么要使用 onSubmit={this.onCommentSubmit}>?@Dominic - Istiak Morsalin
1
@JasonBourne,你可以给回调函数任何你想要的名称,我通常会给事件回调函数命名为onSomethingClick、onMouseMove、onFormKeyPress等,而不是根据它内部应该执行什么来命名方法,因为有时这会发生变化或在另一个方法中(更易于测试)。 - Dominic
3
@JasonBourne 这是正确且最佳的实践方法,在两种情况下都适用,参见 http://jsfiddle.net/ferahl/b125o4z0/。 - Dominic
35
onCommentSubmit 中,你还应该调用 event.preventDefault()event.stopPropagation() 来防止表单重新加载页面(因为它很可能是一个具有空白 action 属性的表单)。 - jamesfzhang
2
这对我没有任何作用。表单仍然无法在“回车”上提交。 - Nick Res
显示剩余12条评论

78

这个问题上次得到解答已经过去好几年了。 React在2017年引入了“Hooks”,而“keyCode”已被弃用。

现在我们可以这样写:

  useEffect(() => {
    const listener = event => {
      if (event.code === "Enter" || event.code === "NumpadEnter") {
        console.log("Enter key was pressed. Run your function.");
        event.preventDefault();
        // callMyFunction();
      }
    };
    document.addEventListener("keydown", listener);
    return () => {
      document.removeEventListener("keydown", listener);
    };
  }, []);

当组件首次加载时,此代码会在keydown事件上注册一个监听器。在组件被销毁时,它会移除该事件的监听器。


1
我正在尝试使用formData useState() hook提交表单,但它正在提交“默认”值 - 我假设它基本上是一个闭包,只能使用定义listener时的值(?) - 我应该只是触发提交按钮的点击吗?还是有一种方法直接调用executeSearch()函数,但让它使用更新后的formData状态? - Code Jockey
这种方法不能在React类中使用。同时要明确的是,已经被弃用的keyCode是DOM keyCode:https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode而不是React的一部分。 - Paul Odeon
1
同样地,对于那些试图防止回车键触发表单提交的人,使用event.preventDefault()作为callMyFunction()的替代品。 - vulpxn
@vulpxn 非常好的观点!大多数人可能不想执行默认操作,所以我已经编辑了我的答案,现在包括这行。 - WSBT
1
这很棒,但我喜欢这个 https://dev59.com/Ib_qa4cB1Zd3GeqPI4Dw#66213831 - Jack Riley

26
使用keydown事件来实现:
   input: HTMLDivElement | null = null;

   onKeyDown = (event: React.KeyboardEvent<HTMLDivElement>): void => {
      // 'keypress' event misbehaves on mobile so we track 'Enter' key via 'keydown' event
      if (event.key === 'Enter') {
        event.preventDefault();
        event.stopPropagation();
        this.onSubmit();
      }
    }

    onSubmit = (): void => {
      if (input.textContent) {
         this.props.onSubmit(input.textContent);
         input.focus();
         input.textContent = '';
      }
    }

    render() {
      return (
         <form className="commentForm">
           <input
             className="comment-input"
             aria-multiline="true"
             role="textbox"
             contentEditable={true}
             onKeyDown={this.onKeyDown}
             ref={node => this.input = node} 
           />
           <button type="button" className="btn btn-success" onClick={this.onSubmit}>Comment</button>
         </form>
      );
    }

1
这会导致某些非罗马语言的表单过早提交。例如,在输入日语时,您需要使用“Enter”从众多字符选项中进行选择。当用户进行字符选择时,您不希望提交文本。 - hayata_suenaga

26

如果您想监听"Enter"键,可以使用onKeydown属性,在React文档中可以了解相关信息。

此外,这是一个CodeSandbox示例。

const App = () => {
    const something=(event)=> {
        if (event.keyCode === 13) {
            console.log('enter')
        }
    }
return (
    <div className="App">
        <h1>Hello CodeSandbox</h1>
        <h2>Start editing to see some magic happen!</h2>
        <input  type='text' onKeyDown={(e) => something(e) }/>
    </div>
);
}

4
这个方法很有效,但在2020年,“event.keyCode”已被弃用,请使用“event.key”。另外,如果你想监听“Enter”键,代码应为: "event.key === "Enter"。 - Timbokun

4
import React, { useEffect, useRef } from 'react';

function Example() {

    let inp = useRef();
    useEffect(() => {
        if (!inp && !inp.current) return;
        inp.current.focus();
        return () => inp = null;
    });

    const handleSubmit = () => {
        //...
    }

    return (
        <form
            onSubmit={e => {
                e.preventDefault();
                handleSubmit(e);
            }}
        >
            <input
                name="fakename"
                defaultValue="...."
                ref={inp}
                type="radio"
                style={{
                    position: "absolute",
                    opacity: 0
                }}
            />
            <button type="submit">
                submit
            </button>
        </form>
    )
}

在弹出窗口中,有时仅将表单绑定并将onSubmit传递到表单中不起作用,因为表单可能没有任何输入。

在这种情况下,如果通过document.addEventListener将事件绑定到文档,它将在应用程序的其他部分引起问题。
为了解决这个问题,我们应该包装一个表单,并在其中放置一个被CSS隐藏的输入项,然后通过ref聚焦在该输入上,它就能正确工作了。

3

如果您没有将表单放在<form>标签内,您可以在componentDidMount()中使用以下代码:

componentDidMount = () => {
      document.addEventListener("keydown", (e) => 
        e.code === "Enter" && console.log("my function"))
    }
    
componentDidMount() //<-- remove this, it's just for testing here


2
useEffect(() => {
const keyEnter = event => {
      if (event.key === 'Enter') {
        event.preventDefault()
      }
    }

    document.addEventListener('keydown', keyEnter)

    return () => {
      document.removeEventListener('keydown', keyEnter)
    }
    }, [])

1

我发现这种方法更加简单。监听要提交的输入框上的keyDown事件,当按下“Enter”键时触发,并使用条件三元运算符处理提交操作,如下所示,全部在一行中。
这种方法主要用于订阅电子报等无需按钮提交的情况。希望对你有所帮助。

<input 
     type="email" 
     placeholder="Email" 
     onKeyDown={e => e.key === 'Enter' ? handleSubmit : ''} />


1

您可以在中间不添加任何内容的情况下使用<button type='submit'></button>标签。


1

您可以仅更改按钮类型 => 按钮为提交

    <form
        onSubmit={e => {
            e.preventDefault();
            handleSubmit(e);
        }}
       >
        <input
            name="developers"
            defaultValue="submit"
            ref={dev}
            type="radio"
        />
        <button type="submit">
            submit
        </button>
    </form>

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