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

MUI useAutocomplete忽略disabled属性,如何禁用弹窗交互?

MUI Base useAutocomplete 禁用状态下拉弹窗控制问题

问题描述

使用MUI Base的useAutocomplete钩子实现自定义Autocomplete组件,其余功能正常,但设置disabled: true后,点击组件仍会打开下拉弹窗。需要确保禁用状态下组件完全不可交互,点击时保持下拉弹窗关闭。

解决方案

核心修改点

  1. 禁用输入框交互:给自定义Input组件添加disabled属性,阻止用户点击或输入触发弹窗,同时通过样式直观提示组件不可用。
  2. 条件渲染弹窗:即使popupOpen状态为true,只要组件处于禁用状态,就不渲染下拉弹窗。

修改后的完整代码

import * as React from "react";
import { useAutocomplete } from "@mui/base/AutocompleteUnstyled";
import { styled } from "@mui/system";

const options = [
  { title: "The Shawshank Redemption", year: 1994 },
  { title: "The Godfather", year: 1972 },
  { title: "The Godfather: Part II", year: 1974 }
];

const Label = styled("label")({
  display: "block"
});

const Input = styled("input")(({ theme, disabled }) => ({
  width: 200,
  backgroundColor: disabled ? "#e0e0e0" : theme.palette.mode === "light" ? "#fff" : "#000",
  color: disabled ? "#999" : theme.palette.mode === "light" ? "#000" : "#fff",
  cursor: disabled ? "not-allowed" : "text",
  border: disabled ? "1px solid #ccc" : "1px solid #000",
  padding: "4px 8px"
}));

const Listbox = styled("ul")(({ theme }) => ({
  width: 200,
  margin: 0,
  padding: 0,
  zIndex: 1,
  position: "absolute",
  listStyle: "none",
  backgroundColor: theme.palette.mode === "light" ? "#fff" : "#000",
  overflow: "auto",
  maxHeight: 200,
  border: "1px solid rgba(0,0,0,.25)",
  "& li.Mui-focused": {
    backgroundColor: "#4a8df6",
    color: "white",
    cursor: "pointer"
  },
  "& li:active": {
    backgroundColor: "#2977f5",
    color: "white"
  },
  "& li": {
    padding: "4px 8px"
  }
}));

export default function Autocomplete() {
  const {
    getRootProps,
    getInputLabelProps,
    getInputProps,
    getListboxProps,
    getOptionProps,
    groupedOptions,
    value,
    popupOpen,
    disabled
  } = useAutocomplete({
    id: "use-autocomplete-demo",
    disabled: true,
    options: options,
    getOptionLabel: (option) => option.title
  });

  return (
    <div>
      <p>value: {JSON.stringify(value)}</p>
      <div {...getRootProps()}>
        <Label {...getInputLabelProps()}>useAutocomplete</Label>
        <Input {...getInputProps()} disabled={disabled} />
      </div>

      {popupOpen && !disabled ? (
        <Listbox {...getListboxProps()}>
          {(groupedOptions as typeof options).map((option, index) => (
            <li {...getOptionProps({ option, index })}>{option.title}</li>
          ))}
        </Listbox>
      ) : null}
    </div>
  );
}

关键细节说明

  • 从useAutocomplete的返回值中解构出disabled状态,用于控制Input的禁用属性和弹窗的渲染条件。
  • 给Input组件添加禁用状态的样式(灰色背景、禁用光标、浅色文本),让用户直观感知组件不可用。
  • 弹窗渲染时增加!disabled的判断,确保禁用状态下无论popupOpen如何变化,都不会显示下拉列表。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 16:55:22