Сфокусируйтесь на следующем поле при нажатии Enter React.js

Я хотел бы найти способ сосредоточиться на следующем поле, когда я нажимаю Enter во входном файле, используя React.js

  @autobind
  handleKeyPress(event){
    if(event.key === 'Enter'){
      this.refs.email.focus();
    }
  }

  @autobind
  handleKeyPressEmail(event){
    if(event.key === 'Enter'){
      this.refs.zip_code.focus();
    }
  }

        <input
          onKeyPress={this.handleKeyPress}
          ref = 'name'
        />

        <input
          onKeyPress={this.handleKeyPressEmail}
          ref = 'email'
        />

        <input
          ref = 'zip_code'
        />

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

Ответ 1

Вы можете использовать componentDidMount и автоматически привязывать ссылки через цикл for-in.

http://codepen.io/jzmmm/pen/PzZgRX?editors=0010

  constructor() {
    super();
    this._handleKeyPress = this._handleKeyPress.bind(this);
  }

  // Loop through the ref object, and bind each of them to onkeypress
  componentDidMount() {
    for (let x in this.refs) {
      this.refs[x].onkeypress = (e) => 
        this._handleKeyPress(e, this.refs[x]);
    }
  }

  // This checks ENTER key (13), then checks if next node is an INPUT
  // Then focuses next input box
  _handleKeyPress(e, field) {
    if (e.keyCode === 13) {
      e.preventDefault(); // Prevent form submission if button present
      let next = this.refs[field.name].nextSibling;

      if (next && next.tagName === "INPUT") {
        this.refs[field.name].nextSibling.focus();
      }
    }
  }

  render() {
    return (
        <form>
          <input type="text" name="name" ref='name' />
          <input type="text" name="email" ref='email' />
          <input type="text" name="zip_code" ref='zip_code' />
        </form>
    );
  }

Ответ 2

Если количество входов умеренное:

function handleEnter(event) {
  if (event.keyCode === 13) {
    const form = event.target.form;
    const index = Array.prototype.indexOf.call(form, event.target);
    form.elements[index + 1].focus();
    event.preventDefault();
  }
}
...
<form>
  <input onKeyDown={handleEnter} />
  <input onKeyDown={handleEnter} />
  <input />
</form>

В противном случае вы можете обернуть input в отдельный компонент:

function MyInput(props) {
  return <input onKeyDown={handleEnter} {...props} />;
}

CodePen

Ответ 3

Вот как мне удалось сделать это проще:

  @autobind
  handleKeyPress(value, event){
    if(event.key === 'Enter'){
      this.refs[event].focus();
    }
  }

    <input
      onKeyPress={(event) => this.handleKeyPress('email', event)}
      ref = 'name'
    />

    <input
      onKeyPress={(event) => this.handleKeyPress('zip_code', event)}
      ref = 'email'
    />

    <input
      ref = 'zip_code'
    />

Ответ 4

В дополнение к ответу Кузнецова, если вы хотите потерять фокус, не переключаясь на следующее поле ввода, вы можете сделать это с помощью element.blur().

Я знаю, что ответ Кузнецова уместен, но я просто хочу добавить это для полноты изложения.

function handleEnter(event) {
  if (event.keyCode === 13) {
    event.target.blur()
  }
}