在按Enter键后调用onChange事件


204

我是Bootstrap的新手,并且一直遇到这个问题。我有一个输入字段,只要输入一个数字,onChange就会调用from函数,但是我希望在输入完整个数字后按“ Enter”键才能调用它。验证功能存在相同的问题-调用时间过早。

var inputProcent = React.CreateElement(bootstrap.Input, {type: "text",
  //bsStyle: this.validationInputFactor(),
  placeholder: this.initialFactor,
  className: "input-block-level",
  onChange: this.handleInput,
  block: true,
  addonBefore: '%',
  ref:'input',
  hasFeedback: true
});

Answers:


404

根据React Doc的说法,您可以监听键盘事件,例如onKeyPressor或onKeyUpnot onChange

var Input = React.createClass({
  render: function () {
    return <input type="text" onKeyDown={this._handleKeyDown} />;
  },
  _handleKeyDown: function(e) {
    if (e.key === 'Enter') {
      console.log('do validate');
    }
  }
});

更新:使用React.Component

这是使用React.Component的代码,它执行相同的操作

class Input extends React.Component {
  _handleKeyDown = (e) => {
    if (e.key === 'Enter') {
      console.log('do validate');
    }
  }

  render() {
    return <input type="text" onKeyDown={this._handleKeyDown} />
  }
}

这是jsfiddle

更新2:使用功能组件

const Input = () => {
  const handleKeyDown = (event) => {
    if (event.key === 'Enter') {
      console.log('do validate')
    }
  }

  return <input type="text" onKeyDown={handleKeyDown} />
}

2
您还希望将验证过程绑定到onBlur事件。
wuct

5
参照输入文本,以更紧凑的方式提供相同的解决方案:<input ref='reference' onKeyPress={(e) => {(e.key === 'Enter' ? doSomething(this.refs.reference.value) : null)}} />
musemind

5
@musemind实际上,您不需要使用ref<input onKeyPress={e => doSomething(e.target.value)}足够了。
wuct

4
@musemind使用类方法而不是内联函数的要点是避免每次onKeyPress触发时创建新函数。这是一个微妙的性能改进。
wuct

1
附加的提琴不再工作了,请检查一下,无论如何还是不错的答案
Pardeep Jain

52

您可以直接在输入字段上使用onKeyPress。onChange函数会在每次输入字段更改时更改状态值,按下Enter键后,它将调用函数search()。

<input
    type="text"
    placeholder="Search..."
    onChange={event => {this.setState({query: event.target.value})}}
    onKeyPress={event => {
                if (event.key === 'Enter') {
                  this.search()
                }
              }}
/>

这个答案对我有用,而不是上面接受的答案。
karthik shankar '18

如果您使用较粗的格式,建议您在render方法之外创建函数,并将其作为参考传递,onKeyPress={this.yourFunc}否则,将在每个render上重新创建胖箭头函数。
维克多

这适用于为输入和父案例编写onKeyPress事件的情况。谢谢。
Naveen Kumar PG,

onKeyPress={event => event.key === 'Enter' && this.search()}
camden_kid

24

Enter当焦点集中在窗体控件(输入)上通常会触发submit窗体本身(不是输入)上的(onSubmit)事件时,,以便可以绑定this.handleInput到表单onSubmit。

或者,您可以将其绑定到blur(onBlur)事件,该事件在input焦点移开时发生(例如,移至可以获取焦点的下一个元素)


3
这比使用干净得多onKeyPress
Blackus '16

1
由于目标不同,event.target.value所以无法思考
Izkata

@Izkata你说的是绝对正确的;我的答案可能需要以其他方式处理控制器handleInput方法中的内容。当用户在专注于输入的同时按下Enter submit键和激活按钮/输入时,按照我的回答进行操作都将覆盖您。

大多数情况下,Web应用程序中没有形式,只有输入,因此此答案与大多数用例无关,恕我直言
vsync

@vsync它可能与大多数无关,但仍然对一部分有效-绝对不是不正确的,我认为这不值得被否决吗?
卢卡,

8

您可以使用 event.key

function Input({onKeyPress}) {
  return (
    <div>
      <h2>Input</h2>
      <input type="text" onKeyPress={onKeyPress}/>
    </div>
  )
}

class Form extends React.Component {
  state = {value:""}

  handleKeyPress = (e) => {
    if (e.key === 'Enter') {
      this.setState({value:e.target.value})
    }
  }

  render() {
    return (
      <section>
        <Input onKeyPress={this.handleKeyPress}/>
        <br/>
        <output>{this.state.value}</output>
      </section>
    );
  }
}

ReactDOM.render(
  <Form />,
  document.getElementById("react")
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="react"></div>


5

反应用户,这是完整性的答案。

React版本16.4.2

您或者希望为每个击键更新,或者仅在提交时获取值。将关键事件添加到组件是可行的,但是官方文档中建议使用其他替代方法。

受控组件与非受控组件

受控

从“ 文档-表单和受控组件”中

在HTML中,表单元素(例如输入,文本区域和select)通常会维护自己的状态并根据用户输入对其进行更新。在React中,可变状态通常保留在组件的state属性中,并且仅使用setState()更新。

我们可以通过使React状态成为“真理的单一来源”来将两者结合起来。然后,呈现表单的React组件还控制后续用户输入时该表单中发生的事情。其值由React这样控制的输入表单元素称为“受控组件”。

如果使用受控组件,则每次更改值时都必须保持状态更新。为此,您将事件处理程序绑定到组件。在文档的示例中,通常是onChange事件。

例:

1)在构造函数中绑定事件处理程序(值保持状态)

constructor(props) {
    super(props);
    this.state = {value: ''};

    this.handleChange = this.handleChange.bind(this);
}

2)创建处理函数

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

3)创建表单提交功能(值取自状态)

handleSubmit(event) {
    alert('A name was submitted: ' + this.state.value);
    event.preventDefault();
}

4)渲染

<form onSubmit={this.handleSubmit}>
    <label>
      Name:
      <input type="text" value={this.state.value} onChange={this.handleChange} />
    </label>
    <input type="submit" value="Submit" />
</form>

如果您使用受控组件,handleChange则将始终触发功能,以更新并保持正确的状态。该状态将始终具有更新的值,并且在提交表单时,将从该状态获取该值。如果您的表单很长,那么这可能是一个缺点,因为您将必须为每个组件创建一个函数,或者编写一个简单的函数来处理每个组件的值更改。

不受控制

来自文档-不受控制的组件

在大多数情况下,我们建议使用受控组件来实现表单。在受控组件中,表单数据由React组件处理。另一种选择是不受控制的组件,其中表单数据由DOM本身处理。

要编写不受控制的组件,您可以使用ref从DOM获取表单值,而不是为每个状态更新编写事件处理程序。

这里的主要区别是您不使用该onChange功能,而是onSubmit表单的形式来获取值,并在必要时进行验证。

例:

1)绑定事件处理程序并创建ref以在构造函数中输入(状态中没有值)

constructor(props) {
    super(props);
    this.handleSubmit = this.handleSubmit.bind(this);
    this.input = React.createRef();
}

2)创建表单提交功能(值取自DOM组件)

handleSubmit(event) {
    alert('A name was submitted: ' + this.input.current.value);
    event.preventDefault();
}

3)渲染

<form onSubmit={this.handleSubmit}>
    <label>
      Name:
      <input type="text" ref={this.input} />
    </label>
    <input type="submit" value="Submit" />
</form>

如果使用不受控制的组件,则无需绑定handleChange功能。提交表单后,该值将从DOM中获取,此时可能会进行必要的验证。也无需为任何输入组件创建任何处理函数。

你的问题

现在,为您的问题:

...我希望在输入完整数字后按Enter

如果要实现此目的,请使用不受控制的组件。如果没有必要,请不要创建onChange处理程序。该enter键将提交表单和handleSubmit功能将被解雇。

您需要做的更改:

删除元素中的onChange调用

var inputProcent = React.CreateElement(bootstrap.Input, {type: "text",
    //    bsStyle: this.validationInputFactor(),
    placeholder: this.initialFactor,
    className: "input-block-level",
    // onChange: this.handleInput,
    block: true,
    addonBefore: '%',
    ref:'input',
    hasFeedback: true
});

处理表单提交并验证您的输入。您需要从表单提交功能中的元素中获取值,然后进行验证。确保在构造函数中创建对元素的引用。

  handleSubmit(event) {
      // Get value of input field
      let value = this.input.current.value;
      event.preventDefault();
      // Validate 'value' and submit using your own api or something
  }

使用不受控制的组件的示例:

class NameForm extends React.Component {
  constructor(props) {
    super(props);
    // bind submit function
    this.handleSubmit = this.handleSubmit.bind(this);
    // create reference to input field
    this.input = React.createRef();
  }

  handleSubmit(event) {
    // Get value of input field
    let value = this.input.current.value;
    console.log('value in input field: ' + value );
    event.preventDefault();
    // Validate 'value' and submit using your own api or something
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          <input type="text" ref={this.input} />
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}

ReactDOM.render(
  <NameForm />,
  document.getElementById('root')
);

3

您也可以像这样编写一些包装函数

const onEnter = (event, callback) => event.key === 'Enter' && callback()

然后在输入中使用它

<input 
    type="text" 
    placeholder="Title of todo" 
    onChange={e => setName(e.target.value)}
    onKeyPress={e => onEnter(e, addItem)}/>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.