React动态表单删除指定条目后state更新正常但渲染错误如何解决
问题修复方案
问题根因
你猜测的方向完全正确,该问题由列表渲染时使用数组索引作为key导致:
React依赖key属性区分列表中的独立元素,当你删除中间条目后,后续所有条目的索引都会整体前移1位,此时React会判定你删除的是列表的最后一个元素,仅移除最后一个DOM节点,前面的DOM节点会复用旧索引对应的元素状态,因此出现数据更新正确但渲染结果错误的问题。
最简单的修复方案
不需要引入额外依赖,只需要修改2处核心逻辑即可:
- 修改条目存储结构,给每个条目加唯一标识
你原来的item_list存的是纯字符串,修改为存储带唯一id的对象,新增条目时用时间戳作为唯一id(普通表单场景下完全不会出现重复,足够使用):
// 假设你原有新增条目的逻辑类似如下,修改为: addItem = () => { const newItem = { id: Date.now(), // 毫秒级时间戳作为唯一id content: this.state.inputValue // 把原来的条目内容存在content字段 } this.setState({ item_list: [...this.state.item_list, newItem], inputValue: '' // 新增后清空输入框 }) }
- 修改列表渲染的key取值
把原来用index作为key的逻辑,改成用每个条目的id,同时可以配套优化删除逻辑,避免后续数组顺序变化导致的误删问题,更稳定:
// 修改删除逻辑 removeItem = (targetId, e) => { this.setState({ item_list: this.state.item_list.filter(item => item.id !== targetId) }, () => { console.log(this.state.item_list); }); } // 修改遍历渲染逻辑 render() { return( //some other code {this.state.item_list.map((val, index) => ( <div key={val.id}> {/* 这里替换为条目自身的唯一id */} <Header> Item #{index+1} </Header> <Form defaultValue={val.content}> </Form> {/* 绑定表单值为条目内容 */} <Button onClick={(e) => this.removeItem(val.id, e)} color="red"> <Icon name= "minus"/>Remove Item </Button> </div> ))} ) }
按照以上步骤修改后,渲染逻辑就可以正确识别要删除的元素,不会再出现展示和数据不一致的问题。
内容的提问来源于stack exchange,提问作者moneymaker
相关产品推荐
相关产品推荐

