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

如何用Jest测试React Sidebar组件?点击切换报错解决

解决TypeError: setToggleSidebar is not a function问题

你的错误来自两个核心问题:

  • 调用useToggleSidebar钩子时未在上下文提供者环境中执行,导致获取的setToggleSidebar为undefined
  • 测试中分开渲染ToggleButton和Sidebar,两者处于独立的SidebarProvider实例中,状态无法同步联动

修复步骤

1. 让钩子在上下文提供者中执行

使用renderHook时,必须通过wrapper参数传入SidebarProvider(以及其他依赖的提供者),确保钩子能正确获取上下文内容。

2. 让ToggleButton和Sidebar共享同一上下文

不要分开调用ComponentRender,而是将两个组件放在同一个JSX片段中渲染,这样它们会共享同一个SidebarProvider实例,点击按钮的状态变化才能同步到侧边栏。

修改后的测试代码

describe("Sidebar", () => {
  test("Toggle Sidebar", () => {
    // 定义包含所有必要提供者的测试wrapper
    const wrapper = ({ children }) => (
      <ReduxProvider>
        <ThemeProvider>
          <SidebarProvider>
            <MemoryRouter initialEntries={["/dashboard"]}>
              {children}
            </MemoryRouter>
          </SidebarProvider>
        </ThemeProvider>
      </ReduxProvider>
    );

    // 通过wrapper确保钩子能获取到上下文
    const { result } = renderHook(() => useToggleSidebar(), { wrapper });

    // 同时渲染两个组件,共享同一上下文
    ComponentRender(
      <>
        <ToggleButton toggleFunc={result.current.toggleSidebar} />
        <Sidebar />
      </>
    );

    fireEvent.click(screen.getByTestId("toggle-button"));

    expect(screen.getByTestId("sidebar")).toHaveClass("HiddenSidebar");
  });
});

额外优化:增加上下文存在校验

可以在useToggleSidebar中增加校验,避免因忘记包裹提供者导致的隐性错误:

const useToggleSidebar = (): IUseToggleSidebar => {
  const { isSidebarShow, setToggleSidebar } = useContext(SidebarContext);

  // 强制校验上下文存在性,提前暴露错误
  if (!setToggleSidebar) {
    throw new Error("useToggleSidebar必须在SidebarProvider组件内部使用");
  }

  const toggleSidebar = () => {
    // 使用函数式更新,无需依赖外部的isSidebarShow状态
    setToggleSidebar(prevState => !prevState);
  };

  return { isSidebarShow, toggleSidebar };
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 15:57:47