React overflow-y滚动列表项重复、首项固定不动问题排查
问题表现
设置了overflow-y: scroll的ul列表容器滚动时出现两个异常:
- 顶部初始列表项固定在原位置,不跟随滚动移动
- 列表出现重复渲染的项
问题效果截图:
相关实现代码
// 遍历食谱列表渲染 showIngList.map((item) => ( <div className="recipe-display" key={item.recipe.url}> <div className="recipe-des"> {/* 食谱名称 */} <h2>{item.recipe.label }</h2> <p>Ingredients:</p> <ul className="list-group list-group-flush"> {/* 遍历单份食谱的配料项渲染 */} {item.recipe.ingredientLines.map((ingredent, key) => ( <li key={key} className="list-group-item"> {ingredent} </li> ))} </ul> <button onClick={closeIngHandler} className="btn btn-danger"> Close </button> </div> </div> ))
排查&修复方案
顶部项固定不跟随滚动问题
按优先级排查以下几点:
- 检查相关元素CSS属性:查看
.list-group、.list-group-item、.recipe-display类的样式,有没有给首个列表项或者顶部元素误加position: sticky/position: fixed属性。sticky会让元素滚动到指定阈值时固定在容器内,fixed会让元素相对视口固定,两者都会出现元素不跟随滚动的现象,误加的话直接删除对应属性即可。 - 确认滚动容器高度是否生效:
overflow-y: scroll生效的前提是容器有明确的固定高度,如果没给ul设置高度,实际触发滚动的是外层页面容器,会出现视觉上元素固定的错觉,给ul加明确高度属性比如height: 500px后再测试滚动效果。 - 排查层叠渲染异常:检查是否给列表项加了错误的
z-index或者transform属性,导致首个列表项的渲染层级高于滚动容器,盖在滚动内容上方不随内容移动,删除异常的层叠属性即可恢复。
列表重复渲染问题
核心是key配置错误或数据源异常:
- 替换内层列表的key值:当前配料列表用数组索引
key={key}作为React diff的唯一标识,当列表出现新增、删除、排序操作时,索引作为key会导致虚拟DOM匹配错误,出现项重复、错位的问题。把内层li的key换成配料本身的唯一值即可,配料是字符串的话可以直接用内容当key:
{item.recipe.ingredientLines.map((ingredent) => ( <li key={ingredent} className="list-group-item"> {ingredent} </li> ))}
- 检查数据源更新逻辑:打印
showIngList确认数组本身是否存在重复项,常见问题是接口请求多次返回数据时,没有做去重就直接把新数据拼接到原有状态数组里,导致数据源本身重复。 - 排查渲染死循环:检查是否在组件渲染阶段直接修改
showIngList状态,导致组件反复触发重渲染、重复往数组里加项,所有状态更新必须通过状态更新函数做不可变更新,不要直接修改原状态数组。
内容的提问来源于stack exchange,提问作者Merox
相关产品推荐
相关产品推荐

