вызвать событие onChange после нажатия клавиши Enter

205

Я новичок в 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
});
Билл Лумберт
источник

Ответы:

405

Согласно 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');
    }
  }
});

Обновление: используйте 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} />
}
wuct
источник
2
И вы также хотели бы связать процесс проверки с onBlurсобытием.
августа
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()
                }
              }}
/>
Адмир
источник
этот ответ работает для меня, а не принятый ответ выше.
Картик Шанкар
Если у вас тяжелая форма, я бы порекомендовал создать функцию вне метода рендеринга и передать ее как ссылку, в onKeyPress={this.yourFunc}противном случае функция жирной стрелки будет создаваться при каждом рендеринге.
Виктор
это работает для случая, когда событие onKeyPress записывается для ввода и родительского случая. Спасибо.
Навин Кумар П.Г.
ИлиonKeyPress={event => event.key === 'Enter' && this.search()}
camden_kid
24

нажатие Enter, когда фокус на элементе управления формы (вход) обычно вызывает submitсобытие (onSubmit) на самой форме (не на входе), чтобы вы могли связать свою this.handleInputформу с формой onSubmit.

В качестве альтернативы вы можете привязать его к blurсобытию (onBlur), inputкоторое происходит при удалении фокуса (например, переход к следующему элементу, который может получить фокус)

Лука
источник
3
Это гораздо более чистый, чем использование onKeyPress.
Блэкус
1
Мысль, поскольку цель отличается, event.target.valueнедоступна
Изката
@Izkata, что вы говорите, абсолютно правильно; Мой ответ может потребовать другого способа обработки вещей в handleInputметоде контроллера . Выполнение в соответствии с моим ответом охватило бы вас как при нажатии пользователем submitклавиши ввода, когда он сфокусирован на вводе, так и при активации кнопки / ввода.
Лука
В большинстве ситуаций в веб-приложениях нет форм, только входные данные, поэтому этот ответ не относится к большинству вариантов использования, ИМХО
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>

onmyway133
источник
5

Реагируйте на пользователей, вот ответ для полноты.

Реагировать на версию 16.4.2

Вы либо хотите обновить для каждого нажатия клавиши, либо получить значение только при отправке. Добавление ключевых событий в компонент работает, но есть альтернативы, рекомендованные в официальных документах.

Контролируемые и неконтролируемые компоненты

Управляемая

Из Документов - Формы и Контролируемые компоненты :

В HTML элементы формы, такие как input, textarea и select, обычно поддерживают свое собственное состояние и обновляют его на основе пользовательского ввода. В React изменяемое состояние обычно сохраняется в свойстве state компонентов и обновляется только с помощью setState ().

Мы можем объединить их, сделав состояние Реакта «единственным источником истины». Затем компонент 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) Привязать обработчик события и создать ссылку для ввода в конструкторе (значение не сохраняется в состоянии)

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)}/>
Дэвид Алш
источник