在功能组件中,如何将下一次输入集中在按下回车键上?(TAB行为)



我想实现TAB行为,但需要按ENTER键。

这是我试图解决的问题,但由于没有使用Refs,它不起作用。

我的想法是在每个输入中说明下一个应该关注哪个元素,然后Enter keyup事件处理程序将该值设置为新的关注字段。

我见过使用useHook的例子,但我不知道如何使用它,而不为每个输入发送大量的useState

下面是一个代码的沙盒。

import React, { useState, useEffect } from "react";
function Form(props) {
// Holds the ID of the focused element
const [focusedElementId, setFocusedElementId] = useState("input-one");
// The actual focusing, after each re-render
useEffect(() => {
document.getElementById(focusedElementId).focus();
}, []);
useEffect(() => {
console.log("STATE:", focusedElementId);
}, [focusedElementId]);
// When Enter is pressed, set the focused state to the next element ID provided in each input
function handleKeyUp(e) {
e.which = e.which || e.keyCode;
if (e.which == 13) {
let nextElementId = e.target.attributes["data-focus"].value;
console.log(`HANDLER: Enter - focusing ${nextElementId}`);
setFocusedElementId(nextElementId);
}
}
return (
<div>
<div className="form-items" style={{ display: "flex" }}>
<div className="input-group">
<label>{"Input One"}</label>
<br />
<input
type={"text"}
id={"input-one"}
onKeyUp={handleKeyUp}
data-focus={"input-two"}
/>
</div>
<div className="input-group">
<label>{"Input Two"}</label>
<br />
<input
type={"text"}
id={"input-two"}
onKeyUp={handleKeyUp}
data-focus={"input-three"}
/>
</div>
<div className="input-group">
<label>{"Input Three"}</label>
<br />
<input
type={"text"}
id={"input-three"}
onKeyUp={handleKeyUp}
data-focus={"input-one"}
/>
</div>
</div>
</div>
);
}
export default Form;

我设法让它与refs一起工作。

这是沙盒。

它看起来既简单又干净,但我仍然对你的意见感到好奇。

import React from "react";
function Form() {
let one = React.createRef();
let two = React.createRef();
let three = React.createRef();
// When Enter is pressed, set the focused state to the next element ID provided in each input
function handleKeyUp(e) {
e.which = e.which || e.keyCode;
// If the key press is Enter
if (e.which == 13) {
switch (e.target.id) {
case "input-one":
two.current.focus();
break;
case "input-two":
three.current.focus();
break;
case "input-three":
one.current.focus();
break;
default:
break;
}
}
}
return (
<div>
<div className="form-items" style={{ display: "flex" }}>
<div className="input-group">
<label>{"Input One"}</label>
<br />
<input
type={"text"}
id={"input-one"}
onKeyUp={handleKeyUp}
ref={one}
/>
</div>
<div className="input-group">
<label>{"Input Two"}</label>
<br />
<input
type={"text"}
id={"input-two"}
onKeyUp={handleKeyUp}
ref={two}
/>
</div>
<div className="input-group">
<label>{"Input Three"}</label>
<br />
<input
type={"text"}
id={"input-three"}
onKeyUp={handleKeyUp}
ref={three}
/>
</div>
</div>
</div>
);
}
export default Form;

这里有一个可扩展性更强的版本;只需连接到容器元素:

function onKeyDown(e) {
if (e.key === 'Enter') {
const fields =
Array.from(e.currentTarget.querySelectorAll('input')) ||
[]
const position = fields.indexOf(
e.target // as HTMLInputElement (for TypeScript)
)
fields[position + 1] && fields[position + 1].focus()
}
}

创建了这个挂钩

import  { useCallback, useEffect } from 'react'
export default function useFormTab() {
const keyDownHandler = useCallback((event: KeyboardEvent) => { 
const target = event.target as HTMLButtonElement
if (event.keyCode === 13  && target.nodeName === "INPUT") {
var form = target.form;
var index = Array.prototype.indexOf.call(form, event.target);
// @ts-ignore
form.elements[index + 2].focus();
event.preventDefault();
}
}, []);
useEffect(() => {

document.addEventListener("keydown", keyDownHandler);
return () => document.removeEventListener("keydown", keyDownHandler);
}, [])

}

这与Tim的版本类似,不需要refs,但他的版本对我不起作用,但经过一些调整后对我起作用:

const handleKeyDown = (e) => {
if (e.key === 'Enter') {
const fields = Array.from(document.querySelectorAll('input')) || []
const position = fields.indexOf(e.target)
fields[position + 1] && fields[position + 1].focus()
}
}

在输入时,只需使用onKeyDown={handleKeyDown}

最新更新