如何为Material UI Autocomplete组件添加加载器实现无限滚动功能
实现方案
你可以借助 Autocomplete 组件自带的 renderList 属性自定义列表结构,配合新增的加载状态实现底部加载提示,修改后完整代码如下:
import { useState, useCallback } from 'react'; import { Autocomplete, TextField, CircularProgress, Typography } from '@mui/material'; // 其余原有依赖保持不变 const SearchSelect: React.FC<SearchSelectProps> = (props) => { // 新增加载状态控制 const [isLoading, setIsLoading] = useState(false); const handleLoadMore = useCallback(async () => { // 加载中拦截重复请求 if (isLoading || !props.loadmoreresults) return; setIsLoading(true); try { // 假设loadmoreresults为异步函数,同步方法可去掉async/await await props.loadmoreresults(); } finally { setIsLoading(false); } }, [isLoading, props.loadmoreresults]); return ( <Autocomplete {...props} ListboxProps={{ onScroll: (event: React.SyntheticEvent) => { const listboxNode = event.currentTarget // 增加2px容错阈值,解决滚动精度问题导致的触发失败 if ( listboxNode.scrollTop + listboxNode.clientHeight >= listboxNode.scrollHeight - 2 ) { handleLoadMore() } }, }} // 自定义列表渲染,末尾插入加载提示 renderList={(listProps) => ( <> {listProps.children} {isLoading && ( <div style={{ padding: '8px 16px', display: 'flex', alignItems: 'center', gap: '8px' }}> {/* 不需要环形进度条可直接删掉该行,只保留文字即可 */} <CircularProgress size={16} /> <Typography variant="body2">Loading</Typography> </div> )} </> )} renderInput={(params) => ( <TextField {...params} label={props.label} variant="filled" // 输入框右侧加载提示为可选配置,不需要可直接删除InputProps配置 InputProps={{ ...params.InputProps, endAdornment: ( <> {isLoading ? <CircularProgress color="inherit" size={20} /> : null} {params.InputProps.endAdornment} </> ), }} /> )} /> ) } export default withStyles(styles)(SearchSelect)
注意事项
- 加载状态会同时拦截重复的加载请求,避免短时间内多次触发接口调用
- 如果不需要 MUI 内置的环形进度组件,直接删除对应代码,仅保留 Loading 文字即可满足最低要求
- 如果你的
loadmoreresults是同步方法,去掉async/await语法,在加载逻辑执行完成后手动调用setIsLoading(false)即可
内容的提问来源于stack exchange,提问作者Manzana
相关产品推荐
相关产品推荐

