按Enter键后调用onChange事件

Bil*_*ert 174 javascript twitter-bootstrap reactjs

我是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
});
Run Code Online (Sandbox Code Playgroud)

wuc*_*uct 357

根据React Doc,您可以听取键盘事件,onKeyPress或者onKeyUp不是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');
    }
  }
});
Run Code Online (Sandbox Code Playgroud)

更新:使用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} />
  }
}
Run Code Online (Sandbox Code Playgroud)

这是jsfiddle.

  • 参考输入文本以更紧凑的方式使用相同的解决方案:`<input ref ='reference'onKeyPress = {(e)=> {(e.key ==='Enter'?doSomething(this.refs.reference. value):null)}} />` (5认同)
  • @musemind实际上,你不需要使用`ref`.`<input onKeyPress = {e => doSomething(e.target.value)}`就足够了. (5认同)
  • @musemind使用类方法而不是内联函数的要点是避免每次触发`onKeyPress`时创建一个新函数.这是一个微妙的性能提升. (4认同)
  • 我更喜欢“onKeyUp”,因为它仅在释放按键时触发。另一方面,如果由于某种原因用户按下并按住该键,“onKeyDown”将多次触发。 (3认同)
  • 而且您还希望将验证过程绑定到`onBlur`事件. (2认同)

Adm*_*mir 35

您可以直接在输入字段上使用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()
                }
              }}
/>
Run Code Online (Sandbox Code Playgroud)

  • 或者 `onKeyPress={event =&gt; event.key === 'Enter' &amp;&amp; this.search()}` (4认同)

Luc*_*uca 21

当焦点放在表单控件(输入)上时,按Enter键通常会触发submit表单本身(而不是输入)上的(onSubmit)事件,因此您可以将this.handleInput表单绑定到onSubmit.

或者你可以将它绑定到blur(onBlur)事件上input,当焦点被移除时会发生(例如,选项卡到下一个可以获得焦点的元素)

  • 这比使用`onKeyPress`要干净得多. (3认同)
  • 认为由于目标不同,`event.target.value`不可用 (2认同)
  • 在网络应用程序的**大多数**情况下,没有表单,只有输入,因此这个答案与大多数用例无关,恕我直言 (2认同)
  • @vsync它可能与大多数人无关,但对于一部分仍然有效 - 并且绝对不正确,我认为不值得投反对票? (2认同)
  • @vsync 你应该有一个表单元素以实现可访问性。就像你不应该把所有东西都变成 div 一样。 (2认同)

ckw*_*aba 12

我更喜欢onKeyUp它,因为它仅在松开按键时才会触发。onKeyDown另一方面,如果由于某种原因用户按住该键,则会多次触发。例如,当侦听“按下”按键Enter以发出网络请求时,您不希望多次触发,因为这可能会很昂贵。

// handler could be passed as a prop
<input type="text" onKeyUp={handleKeyPress} />

handleKeyPress(e) {
  if (e.key === 'Enter') {
    // do whatever
  }
}
Run Code Online (Sandbox Code Playgroud)

另外,请远离它,keyCode因为它有时会被弃用。


c-c*_*vez 8

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

反应版本 16.4.2

您要么想为每次击键更新,要么仅在提交时获取值。将关键事件添加到组件中是可行的,但官方文档中推荐了替代方法。

受控与非受控组件

受控

文档 - 表单和受控组件

在 HTML 中,诸如 input、textarea 和 select 之类的表单元素通常会维护自己的状态并根据用户输入进行更新。在 React 中,可变状态通常保存在组件的 state 属性中,并且仅使用 setState() 进行更新。

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

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

例子:

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

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

    this.handleChange = this.handleChange.bind(this);
}
Run Code Online (Sandbox Code Playgroud)

2) 创建处理函数

handleChange(event) {
    this.setState({value: event.target.value});
}
Run Code Online (Sandbox Code Playgroud)

3)创建表单提交函数(值取自状态)

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

4) 渲染

<form onSubmit={this.handleSubmit}>
    <label>
      Name:
      <input type="text" value={this.state.value} onChange={this.handleChange} />
    </label>
    <input type="submit" value="Submit" />
</form>
Run Code Online (Sandbox Code Playgroud)

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

不受控制

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

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

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

这里的主要区别在于您不使用onChange函数,而是使用onSubmit表单来获取值,并在必要时进行验证。

例子:

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

constructor(props) {
    super(props);
    this.handleSubmit = this.handleSubmit.bind(this);
    this.input = React.createRef();
}
Run Code Online (Sandbox Code Playgroud)

2)创建表单提交函数(取自DOM组件的值)

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

3) 渲染

<form onSubmit={this.handleSubmit}>
    <label>
      Name:
      <input type="text" ref={this.input} />
    </label>
    <input type="submit" value="Submit" />
</form>
Run Code Online (Sandbox Code Playgroud)

如果使用不受控制的组件,则无需绑定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
});
Run Code Online (Sandbox Code Playgroud)

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

  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
  }
Run Code Online (Sandbox Code Playgroud)

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

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')
);
Run Code Online (Sandbox Code Playgroud)


Dav*_*lsh 7

您还可以编写一个像这样的小包装函数

const onEnter = (event, callback) => event.key === 'Enter' && callback()
Run Code Online (Sandbox Code Playgroud)

然后将其消耗在您的输入上

<input 
    type="text" 
    placeholder="Title of todo" 
    onChange={e => setName(e.target.value)}
    onKeyPress={e => onEnter(e, addItem)}/>
Run Code Online (Sandbox Code Playgroud)


Dor*_*ian 7

阻止 Enter 在输入上提交表单的示例,在我的例子中,它是谷歌地图位置自动完成输入

<input
  ref={addressInputRef}
  type="text"
  name="event[location]"
  className="w-full"
  defaultValue={location}
  onChange={(value) => setLocation(value)}
  onKeyDown={(e) => {
    if (e.code === "Enter") {
      e.preventDefault()
    }
  }}
/>
Run Code Online (Sandbox Code Playgroud)


onm*_*133 6

您可以使用 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")
)
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)


小智 2

这个解决方案比给出的所有其他解决方案效果更好:

<!-- html -->
<input type="text" onkeydown='handleKeyPress(this)'>
Run Code Online (Sandbox Code Playgroud)

...

// js
function handleKeyPress(e)
{
    if (event.key === 'Enter') 
    {
        // call your method here
    }
}
Run Code Online (Sandbox Code Playgroud)