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

为什么测试Material UI Select搜索框时toHaveFocus返回错误聚焦元素

问题根因

MUI Select 下拉菜单默认开启了自动聚焦第一个菜单项的内置逻辑,该逻辑的执行时机在测试环境(jsdom)中晚于你自定义的 useEffect 聚焦逻辑,导致输入框刚被聚焦就被 MUI 把焦点抢给了作为第一个菜单项的搜索容器。
浏览器实际运行时时序和测试环境存在差异,所以不会出现这个问题。
另外你的 useEffect 依赖数组写法存在问题:searchRef.current 不属于响应式状态,作为依赖放入数组不会触发 effect 重新执行,属于无效依赖。


解决方案

方案1:禁用MUI菜单默认自动聚焦行为(最推荐)

给 MUISelect 组件传入 MenuProps,关闭菜单自动聚焦首个菜单项的逻辑:

<MUISelect
  MenuProps={{
    disableAutoFocusItem: true
  }}
  {/* 其余原有props */}
>
  {/* 原有子元素 */}
</MUISelect>

同时修正你的 useEffect 依赖数组:

useEffect(() => {
  if (searchRef.current && (isOpen || search)) {
    searchRef.current.focus();
  }
// 移除无效的searchRef.current依赖
}, [search, isOpen]);

方案2:延后输入框聚焦的执行时机

如果不想修改MUI默认行为,可以把聚焦逻辑放到下一个宏任务执行,确保覆盖MUI的默认聚焦结果:

useEffect(() => {
  if (searchRef.current && (isOpen || search)) {
    setTimeout(() => {
      searchRef.current.focus();
    }, 0);
  }
}, [search, isOpen]);

方案3:优化搜索框结构(可选优化)

不要把搜索框包在 MUIMenuItem 组件内部,避免它被MUI识别为菜单项参与聚焦逻辑,你可以直接用普通div作为搜索框容器:

<MUISelect> 
  {/* 用普通div替代MUIMenuItem装搜索框 */}
  <div
    onClickCapture={stopImmediatePropagation}
    onKeyDown={(event: React.KeyboardEvent<HTMLDivElement>) => {
      event.stopPropagation();
    }}
    className={searchContainerClasses.root}
  >
    <Input
      inputRef={searchRef}
      endAdornment={<SearchIcon />}
      classes={searchClasses}
      placeholder={searchPlaceholder}
      onChange={onSearch}
      value={search}
    />
  </div>
  {/* 其余菜单项 */}
</MUISelect>

测试代码补充调整

如果选择方案2,可以保留原来的测试逻辑,也可以加短时间的waitFor确保聚焦完成:

it('should focus search input, when searchable and opened', async () => {
  const searchPlaceholder = 'search';
  const { getByText, getByPlaceholderText } = render(
    <Filter {...props} searchable searchPlaceholder={searchPlaceholder} />
  );

  fireEvent.click(getByText(props.placeholder));
  // 可选等待聚焦完成
  await waitFor(() => {
    expect(getByPlaceholderText(searchPlaceholder)).toHaveFocus();
  })
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 15:27:03