如何获取MUI Autocomplete组件过滤后显示的选项数量?
解决MUI Autocomplete获取过滤后选项数量的状态更新警告问题
原代码问题分析
你在filterOptions里直接调用setFilteredOptionsCount会触发警告,原因是filterOptions是Autocomplete内部渲染流程中的同步执行函数——此时Autocomplete正在渲染选项列表,你却在这个阶段触发了父组件的状态更新,React会检测到"在渲染一个组件时更新另一个组件"的异常行为,从而抛出警告。
替代方案
方案一:用useEffect监听输入值与选项变化(适合使用现成Autocomplete组件)
通过同步Autocomplete的输入值到本地状态,然后在useEffect中手动计算过滤后的选项数量。useEffect会在组件渲染完成后执行,不会干扰渲染流程。
import MuiAutocomplete, { createFilterOptions } from "@mui/material/Autocomplete"; import { useState, useEffect } from "react"; import TextField from "@mui/material/TextField"; const filter = createFilterOptions(); const MyComponent = ({ options }) => { const [inputValue, setInputValue] = useState(""); const [filteredOptionsCount, setFilteredOptionsCount] = useState(options.length); // 当输入值或原始选项变化时,重新计算过滤结果数量 useEffect(() => { const filtered = filter(options, { inputValue }); setFilteredOptionsCount(filtered.length); }, [inputValue, options, filter]); return ( <> <MuiAutocomplete options={options} inputValue={inputValue} onInputChange={(_, newValue) => setInputValue(newValue)} renderInput={(params) => <TextField {...params} label="选择选项" />} /> <p>过滤后选项数量: {filteredOptionsCount}</p> </> ); };
方案二:使用useAutocomplete钩子(更灵活,推荐)
MUI提供的useAutocomplete钩子会直接返回内部处理后的filteredOptions,你可以通过监听这个值来更新数量,完全避免重复计算,而且状态更新时机安全。
import { useAutocomplete } from "@mui/material/Autocomplete"; import TextField from "@mui/material/TextField"; import { useState, useEffect } from "react"; const MyComponent = ({ options }) => { const [filteredOptionsCount, setFilteredOptionsCount] = useState(options.length); const { getRootProps, getInputLabelProps, getInputProps, getListboxProps, getOptionProps, filteredOptions, } = useAutocomplete({ options, }); // 监听过滤后的选项变化,更新数量 useEffect(() => { setFilteredOptionsCount(filteredOptions.length); }, [filteredOptions]); return ( <div {...getRootProps()}> <TextField label="选择选项" {...getInputLabelProps()} {...getInputProps()} /> <ul {...getListboxProps()} style={{ listStyle: "none", padding: 0, marginTop: "8px" }}> {filteredOptions.map((option, index) => ( <li {...getOptionProps({ option, index })} style={{ padding: "8px", border: "1px solid #eee", marginBottom: "4px" }}> {option.label || option} </li> ))} </ul> <p>过滤后选项数量: {filteredOptionsCount}</p> </div> ); };
关键说明
- 两种方案都避免了在渲染阶段更新状态,不会触发React的警告。
- 方案二更贴合Autocomplete的内部逻辑,能准确获取组件实际展示的过滤结果(包括分组、排序等额外处理后的结果)。
内容的提问来源于stack exchange,提问作者Camilo
相关产品推荐
相关产品推荐

