React中含useState状态更新的函数内e.target.disabled=true失效如何解决
问题原因
调用setRecordsRight会触发组件重新渲染,你通过e.target直接修改的DOM禁用状态、类名属于原生操作,没有和React状态绑定,重新渲染后左侧表格会按照初始代码逻辑重新生成按钮,之前的原生修改就会被重置,所以出现失效、可以重复添加的问题。
解决方案
把按钮的禁用状态、样式和React状态绑定,通过状态驱动UI变化即可:
- 新增状态记录已经添加过的左侧行标识,推荐用行数据的唯一id,无唯一id时可暂时用索引:
const [addedMarks, setAddedMarks] = useState(new Set())
- 修改左侧按钮的渲染逻辑,动态绑定类名和禁用状态:
<TableBody className = "leftTable"> { recordsLeft === null ? [] : recordsLeft.map((item, index) => ( //<TableCell></TableCell> //Table Contents <button className={addedMarks.has(index) ? "addToggle2" : "addToggle"} id={"addToggle" + index} onClick={(e) => handleAddSwitch(e, item, index)} disabled={addedMarks.has(index)} > <CircleCheckIcon /> Add </button> )) } </TableBody>
- 重写
handleAddSwitch逻辑,无需操作DOM,仅更新状态即可:
function handleAddSwitch(e, item, index) { // 避免重复添加 if (addedMarks.has(index)) return // 更新已添加标记 setAddedMarks(prev => new Set(prev).add(index)) // 更新右侧表格数据 setRecordsRight(prev => [...prev, item]) }
注意事项
如果你的recordsLeft是动态可变化的(比如会新增、删除行),用索引作为标记可能会出现错位,建议给每条recordsLeft的item增加唯一id字段,用id替代index存入addedMarks,稳定性更高。
内容的提问来源于stack exchange,提问作者user17105276
相关产品推荐
相关产品推荐

