如何在MUI Autocomplete组件末尾添加加载更多按钮
给MUI Autocomplete添加「加载更多」按钮实现方案
核心实现思路
借助MUI Autocomplete的renderListbox属性自定义列表内容,在选项列表末尾追加加载按钮,结合状态管理实现分页加载逻辑,避免一次性加载大量数据导致的性能问题。
完整代码示例
import { useState, useEffect } from 'react'; import { Autocomplete, TextField, Chip, Button, CircularProgress } from '@mui/material'; // 定义数据类型 interface Film { id: number; title: string; } // 模拟分页接口请求 const fetchFilms = async (page: number): Promise<Film[]> => { // 替换为真实接口请求逻辑 await new Promise(resolve => setTimeout(resolve, 1000)); return Array.from({ length: 20 }, (_, i) => ({ id: (page - 1) * 20 + i + 1, title: `电影 ${(page - 1) * 20 + i + 1}` })); }; const LoadMoreAutocomplete = () => { const [items, setItems] = useState<Film[]>([]); const [isLoading, setIsLoading] = useState(false); const [page, setPage] = useState(1); const [isOpen, setIsOpen] = useState(false); // 首次打开组件时加载第一页数据 useEffect(() => { if (isOpen && items.length === 0) { loadMore(); } }, [isOpen, items.length]); // 加载更多数据的核心逻辑 const loadMore = async () => { if (isLoading) return; // 防止重复触发请求 setIsLoading(true); const newItems = await fetchFilms(page); setItems(prev => [...prev, ...newItems]); setPage(prev => prev + 1); setIsLoading(false); }; return ( <Autocomplete multiple id="tags-filled" options={items.map(item => item.title)} defaultValue={items.length > 13 ? [items[13].title] : []} freeSolo open={isOpen} onOpen={() => setIsOpen(true)} onClose={() => setIsOpen(false)} renderTags={(value: readonly string[], getTagProps) => value.map((option: string, index: number) => ( <Chip variant="outlined" label={option} {...getTagProps({ index })} /> )) } renderInput={(params) => ( <TextField {...params} variant="filled" label="freeSolo" placeholder="Favorites" /> )} // 自定义列表框内容,追加加载更多按钮 renderListbox={(children) => ( <> {children} <div style={{ padding: '8px', textAlign: 'center' }}> {isLoading ? ( <CircularProgress size={24} /> ) : ( <Button onClick={loadMore} variant="text"> 加载更多 </Button> )} </div> </> )} /> ); }; export default LoadMoreAutocomplete;
关键部分说明
- 状态控制:用
items存储已加载的选项数据,isLoading标记请求状态避免重复调用,page记录当前分页页码。 - 初始加载触发:通过
onOpen事件和useEffect监听,在组件首次打开时自动加载第一页数据。 - 列表自定义:
renderListbox接收默认渲染的选项列表children,在其后添加加载按钮区域,根据isLoading状态切换显示加载动画或可点击按钮。 - 加载逻辑:
loadMore函数负责发起分页请求,更新数据列表和页码,同时维护加载状态。
扩展优化点
- 可添加滚动监听,当列表滚动到底部时自动触发
loadMore,替代点击按钮的交互。 - 当接口返回空数据时,可将加载按钮替换为「已加载全部」的提示文本,避免无效请求。
内容的提问来源于stack exchange,提问作者p1e0
相关产品推荐
相关产品推荐

