我的目标是创建一个表单,当您点击返回键时会将其标记到下一个输入元素,并在您输入最后一个输入时提交表单。
这是专为移动设备制作的,因为没有选项可以在浏览器中使用“下一个”按钮而不是“去键盘”按钮(有关详细信息,请参阅this answer)。
我还写了一些代码,但这里的重点是我无法在正确的位置捕获事件,因此表单会在返回后立即提交,或者当我阻止事件时,焦点会改变在我回击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'));
答案 0 :(得分:2)
我不认为您正在使用最佳方法,让我解释一下。输入的聚焦由本机DOM元素的focus
方法完成。要根据哪个输入具有当前焦点来了解要关注的输入是必须在这些输入的容器中实现的逻辑,即您的Application
组件。
我对您的代码进行了一些重大更改,现在它正在运行:CodePen
让我解释一下:
首先,当按下的键为keyPressed
时,我们会阻止提交输入的'Enter'
事件,以防止表单submit
_onKeyPress(e) {
if (e.key === 'Enter') {
this.props.onSubmit(e);
e.preventDefault();
}
}
我们在componenDidMount
中不需要componentDidUpdate
或TextInput
我们需要的是focus
方法:
focus() {
this.textInput.focus();
}
大多数更改都在Application
组件中进行。首先,我们不需要状态,我们真正需要的是将数组输入,以便我们可以在它们上面调用focus
。
constructor(props) {
super(props);
this.inputs = [];
}
要更改焦点,我们只需要输入的索引来调用focus
组件的TextInput
方法:
_changeFocus(index) {
return e => {
this.inputs[index].focus();
};
}
然后我们需要一种方法将输入添加到this.inputs
,ref
属性是理想的,我已经创建方法_addInput
作为这个的帮助:< / p>
_addInput(index) {
return input => {
this.inputs[index] = input;
};
}
最后,在渲染TextInput
时,您需要将_addInput
传递给ref
和_changeFocus
传递给onSubmit
,并使用各自的索引:
<TextInput ref={this._addInput(0)} onSubmit={this._changeFocus(1)} />
<TextInput ref={this._addInput(1)} onSubmit={this._changeFocus(0)} />
在第二个TextInput
我将焦点更改为第一个,但是提交表单会更有用。