React表格单元格二次点击可编辑功能异常求助
React表格单元格双击编辑功能异常排查
问题场景
需要实现:第一次点击表格单元格时,单元格获得焦点(高亮);第二次点击同一单元格时,输入框获得焦点并可编辑。但当前代码需要多次点击才会显示可编辑输入框。
错误分析
- 状态逻辑混淆:仅用
currentIndex一个状态同时管理「选中」和「编辑」两种状态,导致第一次点击就直接渲染输入框,不符合“先选中、再编辑”的需求,同时因React状态更新的异步特性,容易出现点击响应延迟的问题。 - 输入框只读判断冗余:输入框的
readOnly属性依赖与显示输入框相同的条件,逻辑重复且不合理。 - 状态更新不规范:修改表格数据时仅做了数组的浅拷贝,内层对象仍为原引用,虽然能触发更新,但不符合React状态不可变的原则,可能引发潜在的状态异常。
修正方案
拆分状态,分别管理「选中单元格」和「编辑单元格」,同时规范状态更新逻辑:
修正后的完整代码
import React, { useState } from 'react'; function App() { // 存储选中的单元格(仅高亮) const [selectedCell, setSelectedCell] = useState(null); // 存储正在编辑的单元格 const [editingCell, setEditingCell] = useState(null); const [array, setArray] = useState(Array.from({ length: 4 }, () => Array.from({ length: 4 }, () => ({ color: "", text: "", })) )); function selectCell(row, col) { // 点击已选中的单元格,进入编辑状态 if (selectedCell?.row === row && selectedCell?.col === col) { setEditingCell({ row, col }); } else { // 点击未选中的单元格,切换选中状态并退出编辑 setSelectedCell({ row, col }); setEditingCell(null); } } function handleText(text, row, col) { // 规范状态更新:深拷贝二维数组及内层对象 const newArray = array.map(rowItem => rowItem.map(cell => ({ ...cell })) ); newArray[row][col].text = text; setArray(newArray); } function changeColor(color) { if (selectedCell) { const newArray = array.map(rowItem => rowItem.map(cell => ({ ...cell })) ); newArray[selectedCell.row][selectedCell.col].color = color; setArray(newArray); } } return ( <div className="App" style={{ display: "flex", flexDirection: "column", justifyContent: "center", alignItems: "center" }}> <div style={{ marginTop: "100px" }}> <button onClick={() => changeColor("red")}>Red</button> <button onClick={() => changeColor("blue")}>Blue</button> <button onClick={() => changeColor("green")}>Green</button> </div> <div style={{ marginTop: "100px" }}> {array.map((arr, rowIndex) => ( <div key={rowIndex} style={{ display: "flex" }}> {arr.map((item, colIndex) => ( <div onClick={() => selectCell(rowIndex, colIndex)} key={colIndex} style={{ width: 100, height: 50, margin: 2, display: 'flex', alignItems: "center", justifyContent: "center", backgroundColor: item.color, border: selectedCell && selectedCell.row === rowIndex && selectedCell.col === colIndex ? "2px solid black" : "1px solid black" }} > {editingCell && editingCell.row === rowIndex && editingCell.col === colIndex ? ( <input type="text" style={{ width: 90, height: 40, backgroundColor: item.color }} value={item.text} autoFocus // 编辑时自动获取焦点 onChange={(e) => handleText(e.target.value, rowIndex, colIndex)} /> ) : `${item.text}`} </div> ))} </div> ))} </div> </div> ); } export default App;
关键修改点
- 新增
selectedCell和editingCell两个状态,分别管理选中和编辑状态,实现“第一次点击选中、第二次点击编辑”的逻辑。 - 输入框添加
autoFocus属性,进入编辑时自动获取焦点,提升交互体验。 - 状态更新时采用深拷贝方式,确保React状态的不可变性,避免潜在异常。
- 移除冗余的
readOnly判断,编辑状态下直接渲染可编辑的输入框。
内容的提问来源于stack exchange,提问作者Avinash sirohi
相关产品推荐
相关产品推荐

