React中使用useRef钩子后无法实现元素焦点切换问题
解决MUI Input组件ref聚焦无效的问题
问题出在哪?
你给MUI的Input组件绑ref,拿到的其实是外层的容器div(就是你控制台打印的那个带MuiInputBase-root类的元素),不是真正的原生input框。调用div的focus()自然不会让输入框获得焦点。
另外,如果你的表格有多行,所有Barcode列的Input都绑同一个barcodeRef,最后这个ref只会指向最后一行的Input容器,这也会导致聚焦不符合预期(比如你想聚焦新添加的行,结果聚焦到最后一行)。
怎么改?
1. 换用MUI提供的inputRef属性
MUI的Input组件专门提供了inputRef属性,用来获取原生input元素的引用,用它替代原来的ref即可:
修改Input的绑定代码:
<Input // 把ref替换为inputRef inputRef={column.accessorKey === "Barcode" ? barcodeRef : null} value={row[column.accessorKey] || ""} onChange={(event) => handleSaveCell( rowIndex, column.accessorKey, event.target.value ) } />
2. 原聚焦逻辑现在就能生效
修改后再运行原有的聚焦代码,就能成功让输入框获得焦点:
useEffect(() => { setTimeout(() => { console.log("现在拿到的是原生input元素:", barcodeRef.current); barcodeRef.current && barcodeRef.current.focus(); }, 500) }, [tableData]);
如果需要聚焦特定行(比如新增的行)
如果你的需求是给某一行的Barcode输入框聚焦,而非默认的最后一行,建议用数组存储ref,配合状态控制:
// 用useRef存储所有Barcode输入框的引用 const barcodeRefs = useRef([]); // 状态记录要聚焦的目标行索引 const [focusTargetRow, setFocusTargetRow] = useState(null); // 渲染时给每一行的Barcode输入框绑定ref {tableData.map((row, rowIndex) => ( <TableRow key={rowIndex}> {columns.map( (column) => !column.hidden && ( <TableCell key={column.accessorKey} style={{ width: column.width }}> {column.accessorKey === "Barcode" ? ( <Input inputRef={(el) => barcodeRefs.current[rowIndex] = el} value={row[column.accessorKey] || ""} onChange={(event) => handleSaveCell(rowIndex, column.accessorKey, event.target.value)} /> ) : ( // 其他列的Input代码保持不变 )} </TableCell> ) )} </TableRow> ))} // 聚焦逻辑:当目标行索引变化时,聚焦对应行的输入框 useEffect(() => { if (focusTargetRow !== null && barcodeRefs.current[focusTargetRow]) { barcodeRefs.current[focusTargetRow].focus(); // 可选:聚焦完成后重置状态 setFocusTargetRow(null); } }, [focusTargetRow, tableData]); // 示例:新增行后调用setFocusTargetRow(新行索引),即可聚焦该行的Barcode输入框
内容的提问来源于stack exchange,提问作者Ayush Mishra
相关产品推荐
相关产品推荐

