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

如何获取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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 12:41:06