按Enter键后调用onChange事件

时间:2015-07-07 14:57:16

标签: javascript twitter-bootstrap reactjs

我是Bootstrap的新手并坚持这个问题。我有一个输入字段,只要输入一个数字,就会调用来自onChange的函数,但我希望在输入整个数字时按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
});

9 个答案:

答案 0 :(得分:312)

根据React Doc,您可以收听键盘事件,例如onKeyPressonKeyUp,而不是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

答案 1 :(得分:28)

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

答案 2 :(得分:21)

当表单控件(输入)上的焦点通常在表单本身(而不是输入)上触发submit(onSubmit)事件时,按输入,这样您就可以绑定{ {1}}到onSubmit上的表单。

或者,您可以将其绑定到this.handleInput上的blur(onBlur)事件,该事件在删除焦点时发生(例如,标签到可以获得焦点的下一个元素)

答案 3 :(得分:4)

您可以使用event.key

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

class Form extends React.Component {
  constructor(props) {
    super(props)

    this.handleKeyPress = this.handleKeyPress.bind(this)
  }

  handleKeyPress(event) {
    if (event.key === 'Enter') {
      console.log('enter key pressed')
    }
  }

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

答案 4 :(得分:1)

与用户互动,这是完整性的答案。

  

反应版本16.4.2

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

受控组件与非受控组件

受控

来自Docs - Forms and Controlled components

  

在HTML中,通常使用输入,文本区域和选择等表单元素   保持自己的状态并根据用户输入进行更新。在React中   可变状态通常保留在组件的状态属性中,   并且仅使用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函数,以更新并保持正确的状态。该状态将始终具有更新的值,并且在提交表单时,将从该状态获取该值。如果您的表单很长,那么这可能是一个缺点,因为您将不得不为每个组件创建一个函数,或者编写一个简单的函数来处理每个组件的值更改。

不受控制

Docs - Uncontrolled component

  

在大多数情况下,我们建议使用受控组件来实施   形式。在受控组件中,表单数据由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')
);

答案 5 :(得分:1)

阻止 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()
    }
  }}
/>

答案 6 :(得分:0)

您还可以编写类似这样的小包装函数

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)}/>

答案 7 :(得分:0)

这是使用基于类的组件的常见用例:父组件提供回调函数,子组件呈现输入框,当用户按下Enter键时,我们将用户的输入传递给父组件。

class ParentComponent extends React.Component {
  processInput(value) {
    alert('Parent got the input: '+value);
  }

  render() {
    return (
      <div>
        <ChildComponent handleInput={(value) => this.processInput(value)} />
      </div>
    )
  }
}

class ChildComponent extends React.Component {
  constructor(props) {
    super(props);
    this.handleKeyDown = this.handleKeyDown.bind(this);
  }

  handleKeyDown(e) {
    if (e.key === 'Enter') {
      this.props.handleInput(e.target.value);
    }
  }

  render() {
    return (
      <div>
        <input onKeyDown={this.handleKeyDown} />
      </div>
    )
  }      
}

答案 8 :(得分:0)

我更喜欢 onKeyUp 因为它只在释放键时触发。另一方面,如果用户出于某种原因按住键,onKeyDown 将触发多次。例如,在侦听“按下”Enter 键以发出网络请求时,您不希望多次触发,因为它可能很昂贵。

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

handleKeyPress(e) {
if (e.key === 'Enter') {
  // do whatever
}

}

另外,请远离 keyCode,因为它会在一段时间内被弃用。