React状态未变更但DOM异常变化问题求助
问题原因及解决方案
核心原因
列表渲染未设置唯一
key
React渲染列表时,需要通过key属性识别每个列表项的唯一性。你当前代码仅给<tr>设置了id,但没有为map返回的列表项添加key。删除上方项后,列表项索引发生变化,React会复用原有组件实例,由于缺少正确的key,组件的DOM状态(比如文本框内容)无法和新state同步,导致显示异常。页面存在重复
id<tr>和内部三个<TextareaAutosize>都使用item.id作为id属性,违反了HTML中id必须全局唯一的规则,会干扰React的DOM更新逻辑和浏览器的元素识别。comment字段初始值类型问题comment初始值为null,而<TextareaAutosize>的value期望是字符串类型。组件被复用时,null转空字符串的逻辑可能和已编辑的字符串状态冲突,导致DOM内容未正确重置。
修复步骤
1. 为列表项添加唯一key
修改map渲染部分,给<tr>添加key={item.id},同时修改<tr>的id避免重复:
items = this.state.items.map((item) => { return <tr key={item.id} id={`row-${item.id}`}> {/* 其余内容不变 */} </tr> });
2. 确保元素id唯一,统一comment值类型
修改每个<TextareaAutosize>的id,结合字段名保证唯一性,同时将comment的null转为空字符串:
<td><TextareaAutosize onChange={this.editItem} className="tdStyle" name="todo" id={`todo-${item.id}`} value={item.todo} /></td> <td><TextareaAutosize onChange={this.editItem} className="tdStyle" name="details" id={`details-${item.id}`} value={item.details} /></td> <td><TextareaAutosize onChange={this.editItem} className="tdStyle" name="comment" id={`comment-${item.id}`} value={item.comment || ''} /></td> <td><img className="removeBtn" src={remove} id={`delete-${item.id}`} onClick={this.deleteItem} /></td>
3. 调整事件处理中的id获取逻辑
因为元素id格式改变,需要从新的id字符串中拆分出真实的item id:
editItem = (event) => { const column = event.target.name; const id = event.target.id.split('-')[1]; const text = event.target.value; this.setState(prevState => ({ items: prevState.items.map(el => { if (el.id == id) { return {...el, [column]: text}; } return el; }) })) } deleteItem = (event) => { const id = event.target.id.split('-')[1]; this.setState(prevState => ({ items: prevState.items.filter(el => el.id != id), deletedItems: [...prevState.deletedItems, ...prevState.items.filter(el => el.id == id)] })) }
内容的提问来源于stack exchange,提问作者Hejhejhej123
相关产品推荐
相关产品推荐

