繁体   English   中英

使用 react 更改文本输入的焦点

[英]Change focus of text input with react

我的目标是创建一个表单,当您按回车键时,它会将您切换到下一个输入元素,并在您进行最后一个输入时提交表单。

这是为移动设备构建的,因为在浏览器中没有使用“下一步”按钮而不是“转到键盘”按钮的选项(有关此问题的更多信息,请参阅此答案)。

为了更好地形象化这一点,这里有一张图片: 在此处输入图片说明

我也写了一些代码,但这里的重点是我无法在正确的位置捕捉​​事件,所以表单在返回后立即提交或者当我阻止事件时,焦点在我点击后改变返回2次。

请参阅此处的示例: https : //codepen.io/ofhouse/pen/Rgwzxy (我也粘贴了下面的代码)

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

  componentDidMount() {
    if (this.props.focus) {
      this.textInput.focus();
    }
  }

  componentDidUpdate(nextProps) {
    if (nextProps.focus) {
      this.textInput.focus();
    }
  }

  _onKeyPress(e) {
    if (e.key === 'Enter') {
      this.props.onSubmit(e);
    }
  }

  render() {
    return (
      <div>
        <input
          type="text"
          onKeyPress={this._onKeyPress}
          ref={input => {
            this.textInput = input;
          }}
        />
      </div>
    );
  }
}

class Application extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      currentElement: 0,
    };
  }

  _submitForm(e) {
    // If I remove this preventDefault it works, but also the form is submitted --> SiteReload
    e.preventDefault();
  }

  _changeFocus(nextElement) {
    return e => {
      this.setState({
        currentElement: nextElement,
      });
    };
  }

  render() {
    const { currentElement } = this.state;
    return (
      <form>

        <h1>React input focus</h1>

        <TextInput focus={currentElement === 0} onSubmit={this._changeFocus(1)} />
        <TextInput focus={currentElement === 1} onSubmit={this._changeFocus(0)} />

        <div>
          <button type="submit" onClick={this._submitForm}>Submit</button>
        </div>

      </form>
    );
  }
}

ReactDOM.render(<Application />, document.getElementById('app'));

我认为你没有使用最好的方法,让我解释一下。 输入的聚焦是由原生 DOM 元素的focus方法完成的。 要根据哪个输入具有当前焦点来了解要关注哪个输入是必须在这些输入的容器中实现的逻辑,在您的情况下是Application组件。

我对您的代码进行了一些重大更改,现在可以正常工作了: CodePen

让我解释一下:

首先,当按下的键是'Enter'时,我们阻止提交输入的keyPressed事件,以防止表单submit

_onKeyPress(e) {
  if (e.key === 'Enter') {
    this.props.onSubmit(e);
    e.preventDefault();
  }
}

我们不需要TextInput componenDidMountcomponentDidUpdate ,我们只需要一个focus方法:

focus() {
  this.textInput.focus();
}

大多数更改是在Application组件中进行的。 首先,我们不需要状态,我们真正需要的是将输入放在一个数组中,以便我们可以将focus放在它们上。

constructor(props) {
  super(props);

  this.inputs = [];
}

要改变焦点,我们只需要输入的索引来调用TextInput组件的focus方法:

_changeFocus(index) {
  return e => {
    this.inputs[index].focus();
  };
}

然后我们需要一种方法将输入添加到this.inputsref属性将是理想的,我已经创建了_addInput方法作为帮助:

_addInput(index) {
  return input => {
    this.inputs[index] = input;
  };
}

最后,在渲染TextInput您需要将它们_addInput传递给ref并将_changeFocusonSubmit ,以及它们各自的索引:

<TextInput ref={this._addInput(0)} onSubmit={this._changeFocus(1)} />
<TextInput ref={this._addInput(1)} onSubmit={this._changeFocus(0)} />

在第二个TextInput我将焦点更改为第一个,但也许提交表单会更有用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM