悠悠楠杉
网站页面
正文:
在React开发中,表单处理是高频需求,尤其是多输入框场景下的焦点管理常常让开发者头疼。传统的DOM操作方式与React的声明式理念背道而驰,而useRef钩子则提供了一种优雅的解决方案。本文将带你从问题出发,逐步拆解如何用useRef实现高效焦点控制。
想象一个用户注册表单:用户填写完用户名后,期望按回车键自动跳转到密码输入框。若手动通过document.getElementById()操作DOM,不仅代码冗余,还会破坏React的组件化优势。此时,useRef的价值便凸显出来——它能够在不触发重新渲染的情况下,直接访问DOM节点。
useRef的核心是创建一个可变的引用对象,其current属性指向目标DOM元素。以下是一个简单示例:
import { useRef } from 'react';
function SimpleInput() {
const inputRef = useRef(null);
const focusInput = () => {
inputRef.current.focus();
};
return (
<div>
<input ref={inputRef} type="text" />
<button onClick={focusInput}>聚焦输入框</button>
</div>
);
}
面对多个输入框时,可以动态生成ref数组,并通过索引控制焦点跳转。以下是关键实现步骤:
Array.map生成与输入框数量匹配的ref数组:
const inputRefs = useRef([]);
inputRefs.current = Array(4).fill().map((_, i) => inputRefs.current[i] || createRef());
onKeyDown事件中,判断回车键并切换焦点:
const handleKeyDown = (e, index) => {
if (e.key === 'Enter') {
e.preventDefault();
const nextIndex = index + 1;
if (nextIndex < inputRefs.current.length) {
inputRefs.current[nextIndex].current.focus();
}
}
};
function MultiInputForm() {
const inputRefs = useRef([]);
// 初始化refs
inputRefs.current = Array(4).fill().map((_, i) => inputRefs.current[i] || createRef());
const handleSubmit = (e) => {
e.preventDefault();
const formData = inputRefs.current.map(ref => ref.current.value);
console.log('表单数据:', formData);
};
return (
<form onSubmit={handleSubmit}>
{['用户名', '邮箱', '密码', '确认密码'].map((label, index) => (
<div key={index}>
<label>{label}</label>
<input
ref={inputRefs.current[index]}
type={index > 1 ? 'password' : 'text'}
onKeyDown={(e) => handleKeyDown(e, index)}
/>
</div>
))}
<button type="submit">提交</button>
</form>
);
}
ref数组,仅在首次渲染时初始化。useFocusManagement,实现复用。aria-label和键盘导航提示,提升可访问性。ref.current是否存在。useMemo缓存ref数组,避免频繁重建。