嵌套分类Autocomplete组件:选中后重置/清空问题解决
嵌套分类筛选UI的Autocomplete问题解决方案
问题背景
正在构建基于嵌套Autocomplete组件的产品分类筛选UI,通过面包屑展示已选分类,Autocomplete用于选择当前层级的分类。分类为树形结构(最深可达20层),示例如下:
Women > Accessories > Glasses Women > Underwear Men > Shoes > Sandals
用户先从[Women, Men]选择一级分类,选中后Autocomplete会切换到对应二级分类选项,面包屑同步更新。
当前存在的问题
- 选中分类后,Autocomplete仍保留之前的选中值,但选项列表已切换,触发MUI警告:
MUI: The value provided to Autocomplete is invalid. None of the options match with "Women".You can use the `isOptionEqualToValue` prop to customize the equality test.
- 切换分类层级后,输入框仍保留最后选中的选项,希望切换层级时输入框自动清空。
解决方案
核心问题是选中分类后,Autocomplete的选中值未及时重置,导致与新的选项列表不匹配。通过以下步骤解决:
1. 新增状态管理Autocomplete选中值
添加selectedCategory状态,专门控制Autocomplete的当前选中值:
const [selectedCategory, setSelectedCategory] = useState<string | null>(null);
2. 切换层级时重置选中值
在categories(面包屑层级)更新时,同步重置selectedCategory,确保输入框清空且选项匹配:
useEffect(() => { const newOptions = getCurrentCategoriesList(categoriesTree, categories); setOptions(newOptions); setSelectedCategory(null); // 切换层级时清空选中值 }, [categories]);
3. 选中分类后重置输入框
在handleCategoryChange函数中,添加重置逻辑,确保选完分类后输入框立即清空:
function handleCategoryChange(_event, newValue: string | null) { if (newValue != null) { setCategories([...categories, newValue]); setSelectedCategory(null); // 选完分类后重置输入框 } }
4. 绑定状态到Autocomplete
给Autocomplete组件添加value属性,关联selectedCategory状态:
<Autocomplete value={selectedCategory} // 绑定选中值状态 // 其他属性... />
完整修改后的代码
import { useState, useEffect } from "react"; import { Box, Button, FormControl, TextField } from "@mui/material"; import Autocomplete from "@mui/material/Autocomplete"; type CategoryLevel = { [key: string]: CategoryLevel; }; function getCurrentCategoriesList( categoriesTree: CategoryLevel, categories: string[] ) { let subTree = categoriesTree; for (const category of categories) { subTree = subTree[category] || {}; } if (!subTree) { return []; } return Object.keys(subTree); } export default function App() { const [open, setOpen] = useState(false); const [options, setOptions] = useState<string[]>([]); const [categories, setCategories] = useState<string[]>([]); const [selectedCategory, setSelectedCategory] = useState<string | null>(null); useEffect(() => { const newOptions = getCurrentCategoriesList(categoriesTree, categories); setOptions(newOptions); setSelectedCategory(null); }, [categories]); function handleCategoryChange(_event, newValue: string | null) { if (newValue != null) { setCategories([...categories, newValue]); setSelectedCategory(null); } } return ( <Box className="App"> <h1>Hello Categories</h1> <h2> <Button onClick={() => setCategories([])}>Reset</Button> {categories.join(" > ")} </h2> <FormControl> <Autocomplete disableClearable open={open} sx={{ width: 300 }} onClose={() => { setOpen(false); }} onOpen={() => { setOpen(true); }} noOptionsText="No Categories" options={options} value={selectedCategory} onChange={handleCategoryChange} renderInput={(params) => ( <TextField {...params} label={ getCurrentCategoriesList(categoriesTree, categories).length > 0 ? "Category" : "NA" } variant="standard" /> )} /> </FormControl> </Box> ); } const categoriesTree = { Men: { "T-Shirts": { Polos: {}, }, Shorts: {}, Jackets: {}, Accessories: { Glasses: {}, Belts: {}, Underwear: {}, Socks: {}, }, }, Women: { "T-Shirts": { Polos: {}, }, Shorts: {}, Jackets: {}, Accessories: { Glasses: {}, Belts: {}, Underwear: {}, Socks: {}, }, }, };
内容的提问来源于stack exchange,提问作者ItayB
相关产品推荐
相关产品推荐

