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

MUI Autocomplete状态变更时下拉列表上移问题求助

MUI Autocomplete下拉列表展开/折叠时上移问题解决

我用MUI的Autocomplete组件开发了带展开/折叠功能的组件,展开状态存在expandedPortfolios状态中。点击箭头触发handleExpand修改状态时,组件能正常重新渲染,但下拉列表会出现上移的问题。尝试过用shouldComponentUpdate处理,结果导致状态变更后组件无法渲染,引发新问题。

相关代码

handleExpand函数

handleExpand = (portfolioName) => {
    var portfolio = (this.state.portfoliosAsGroup || []).find(p => p.name == portfolioName);
    if (portfolio) {
        let portfolioId = portfolio.id;
        let current = this.state.expandedPortfolios;
        let Ids = [];
        if (current.includes(portfolioId)) {
            Ids = current.filter((i) => i !== portfolioId);
        } else {
            Ids.push(...current, portfolioId);
        }
        this.setState({ expandedPortfolios: Ids, expand: !this.state.expand });
    }
}

renderGroup配置

renderGroup={(params) => (
    <>
        <div style={{ display: "flex", alignItems: "center", height: "20px", marginTop: '15px' }}>
            {params.group != dropdownGroupTags.all && <IconButton size="small" onClick={() => this.handleExpand(params.group)}>
                {(!(this.state.expandedPortfolios || []).includes(this.getPortfolioIdByName(params.group)) ?
                    <ExpandLessIcon /> : <ExpandMoreIcon />)}
            </IconButton>}
            {params.group != dropdownGroupTags.all ? <WarehouseIcon /> : <AccountBalanceIcon />}
            <Button onClick={() => params.group != "Unportfolio" && this.handleCompanyChange(this.createCompanyGroupChangeText(params.group), params.group)}>
                <Typography variant="subtitle1" sx={{ fontWeight: 'bold' }}>
                    {params.group}
                </Typography>
            </Button>
            <div style={{
                marginLeft: 'auto',
                marginRight: '30px'
            }}>
                <Typography align="right" variant="subtitle1" sx={{ fontWeight: 'bold' }}>
                    {params.group != dropdownGroupTags.all && `${(params.children || []).length} Unit`}
                </Typography>
            </div>
        </div>
        <br />
        {(this.state.expandedPortfolios || []).includes(this.getPortfolioIdByName(params.group)) ? params.children : []}
    </>
)}

问题示例

示例动图

解决方法

  • 禁用Popper自动位置调整:通过PopperProps关闭翻转和溢出修正,避免下拉列表因内容变化重新计算位置时偏移:
    <Autocomplete
      // 其他原有props
      PopperProps={{
        modifiers: [
          { name: 'flip', enabled: false },
          { name: 'preventOverflow', enabled: false }
        ]
      }}
    />
    
  • 移除多余状态更新:handleExpand中的expand: !this.state.expand是冗余状态,仅保留expandedPortfolios更新即可,减少不必要的渲染触发:
    this.setState({ expandedPortfolios: Ids });
    
  • 保持DOM结构稳定:折叠状态下不要返回空数组,改用空容器占位,避免DOM节点数量突变导致布局计算异常:
    {(this.state.expandedPortfolios || []).includes(this.getPortfolioIdByName(params.group)) 
      ? params.children 
      : <div style={{ height: 0, overflow: 'hidden' }} />}
    
  • 保持下拉面板挂载状态:设置keepMounted: true让下拉面板始终挂载(即使隐藏),避免重新挂载时的位置计算错误:
    <Autocomplete
      // 其他原有props
      PopperProps={{ keepMounted: true }}
    />
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 02:45:34