You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在MUI Autocomplete中实现按作者的唯一分组

问题:MUI Autocomplete分组重复,同一作者书籍分散

问题说明

使用MUI的Autocomplete组件实现搜索栏建议项分组时,同一作者的书籍ID不连续会生成重复的作者分组头,仅当ID连续时分组正常。需要将同一作者的所有书籍归到同一个分组下。

数据结构

[
  { 
    "id" : 1,
    "bookName" : "it starts with us",
    "author" : "Colin Hoover"
  },
  { 
    "id" : 2,
    "bookName" : "it ends with us",
    "author" : "Colin Hoover"
  },
  { 
    "id" : 3,
    "bookName" : "The great Gatsby",
    "author" : "Scott Fitzgerald"
  },
  { 
    "id" : 4,
    "bookName" : "To Kill a mocking bird",
    "author" : "Harper Lee"
  },
  { 
    "id" : 5,
    "bookName" : "Remainders of Him",
    "author" : "Colin Hoover"
  }
]

期望渲染效果

Colin Hoover // 作者名作为分组标题,下方列出其书籍
    Remainders of Him 
    It Ends with us
    It starts with us 
    ... 该作者的其他书籍
Scott Fitzgerald
    The great Gatsby
Harper Lee
    To Kill a mocking bird

当前代码

imports ...

export default function JobSearch () {
const [ books, setBooks ] = useState<Book[]>([]);
const [ searchTerm, setSearchTerm ] = useState<string>('');
// using redux
const dispatch = useAppDispatch();
const { status } = useAppSelector ( state => state.menu );

useEffect(() => {
    agent.Books.getBooks() // my endpoint for getting the books
    .then((books) => { setBooks(books);
                       console.log(books)})
    .catch((error) => console.log(error))
}, []);

const suggestions = books.map((book) => {
const bookDetail = `${book.name} by ${book.author}` // 注意:这里book.name应该是book.bookName,数据结构中字段是bookName
return {
    bookDetail,
    ...book
}});

const handleChangeInput = ( event : any ) => {
 setSearchTerm( event.target.value);
 console.log(event.target.value);
}


    return (
        <Fragment>
           <Autocomplete
             open = { status.name === "autoCompleteMenu" && status.open }
             autoHighlight = {true}
             autoComplete = {true}
             noOptionsText = {`Search for ${searchTerm}`}
             onOpen = { () => {
                dispatch(setOpenMenu("autoCompleteMenu"));
            }}
             onClose = { () => dispatch(setCloseMenu("autoCompleteMenu"))}
             options = {suggestions.sort((a, b) => -b.bookDetail.localeCompare(a.bookDetail))} 
             isOptionEqualToValue = {(option, value) => option.bookDetail === value.bookDetail}
             groupBy = {(option) => option.author} // I want all books sorted under same author
             getOptionLabel={(option) => option.bookDetail}
             renderInput = {(params) => (
                <TextField { ...params} 
                 label = {'search ...'}
                 onChange = {handleChangeInput}
                 variant = {'outlined'} />  )} />
        </Fragment>
    )
}

解决方案

问题根源在于当前排序逻辑仅按bookDetail倒序,没有先按作者分组排序,导致同一作者的书籍分散在数组中。MUI Autocomplete的groupBy是遍历数组时,遇到新的分组值就创建新分组头,因此必须让同一作者的所有项连续排列。

修改步骤:

  1. 修正字段错误:book.name改为book.bookName,匹配数据结构中的字段名。
  2. 调整排序逻辑:先按作者名排序,确保同一作者的项连续,再按书名排序。

修改后的关键代码:

// 修正suggestions中的字段错误
const suggestions = books.map((book) => {
  const bookDetail = `${book.bookName} by ${book.author}`
  return {
    bookDetail,
    ...book
  }});

// 修改Autocomplete的options排序逻辑
options={suggestions.sort((a, b) => {
  // 先按作者名升序排列,确保同一作者的项连续
  const authorCompare = a.author.localeCompare(b.author);
  if (authorCompare !== 0) {
    return authorCompare;
  }
  // 作者相同时,按书名升序排列(如需倒序可改为 -a.bookName.localeCompare(b.bookName))
  return a.bookName.localeCompare(b.bookName);
})}

说明:

  • 先按author排序,保证同一作者的所有书籍在数组中连续排列,Autocomplete遍历到这些项时只会生成一个分组头。
  • 作者相同的情况下,可根据需求按书名升序/倒序排列,优化展示顺序。

内容的提问来源于stack exchange,提问作者Himanshu Sharma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 21:15:33