如何实现Material UI Autocomplete无限滚动并解决双滚动条问题
MUI Autocomplete 搭配无限滚动组件的双层滚动冲突解决方案
问题根源
现有实现的冲突本质是组件嵌套逻辑颠倒,且两层滚动容器没有明确职责划分:
- 原代码将无限滚动组件套在Material UI的Paper组件外层,Paper自身默认携带内部滚动能力,无限滚动组件又独立设置了固定高度的滚动区域,自然出现双层滚动条
- 当尝试移除其中一层滚动能力时,会出现逻辑断链:要么Paper关了滚动导致内容溢出无法浏览,要么无限滚动层被隐藏导致收不到滚动事件、无法触发分页拉取
- 额外存在参数配置错误:原代码将全量列表总条数传给了无限滚动组件的
dataLength参数,不符合组件的参数要求,会干扰滚动触发判断
正确实现步骤
- 明确单一滚动职责:仅保留无限滚动组件作为唯一的滚动事件监听、内容滚动渲染容器,其余层级组件全部关闭自身的滚动相关属性
- 调整嵌套层级顺序:将无限滚动组件嵌入Paper组件内部,而非反向包裹
- 覆盖Paper组件的默认滚动样式,彻底移除Paper自身的滚动逻辑
- 修正无限滚动组件的参数取值,匹配组件要求
修正后的核心实现代码
<Autocomplete options={list.data ?? []} getOptionLabel={(option) => option.name} PaperComponent={(params) => ( <Paper {...params} sx={{ overflow: 'hidden', maxHeight: 'none', // 清除内部列表容器的默认滚动限制 '& .MuiAutocomplete-listbox': { maxHeight: 'none', overflow: 'visible', padding: 0 } }} > <InfiniteScroll height={280} dataLength={list.data?.length ?? 0} next={this.handleFetchNext.bind(this)} hasMore={list.data.length < list.total} loader={ <p style={{ textAlign: "center", backgroundColor: "#f9dc01" }}> <b>Loading...</b> </p> } endMessage={ <p style={{ textAlign: "center", backgroundColor: "#f9dc01" }}> <b>Yay! You have seen it all</b> </p> } > {params.children} </InfiniteScroll> </Paper> )} renderInput={(params) => ( <TextField {...params} label="" variant="outlined" /> )} />
注意事项
- 滚动链路中间不要叠加任何带
overflow属性的拦截层,否则无限滚动组件无法监听到滚动到底部的事件,会导致分页API不触发 - 自定义下拉可视高度时,直接调整无限滚动组件的
height参数即可,不要在父容器额外添加滚动相关样式 dataLength参数必须传入当前已经加载完成的条目总数量,不要传入接口返回的全量列表总条数,否则组件的滚动触发判断逻辑会异常
内容的提问来源于stack exchange,提问作者Gauri Padbidri
相关产品推荐
相关产品推荐

