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

NextJS导入自定义钩子时出现'useViewport is not a function'错误

问题排查与解决办法

1. 检查导出与导入的匹配性

这是最常见的触发原因,需确认useViewport的导出方式和导入方式完全一致:

  • 若ViewportContext.tsx中是默认导出:
    // src/context/ViewportContext.tsx
    export default function useViewport() { /* ... */ }
    
    导入时必须用默认导入语法:
    // src/utils/useDeviceType.tsx
    import useViewport from '@/context/ViewportContext';
    
  • 若为命名导出:
    // src/context/ViewportContext.tsx
    export function useViewport() { /* ... */ }
    
    导入时要用解构的命名导入:
    // src/utils/useDeviceType.tsx
    import { useViewport } from '@/context/ViewportContext';
    

2. 确保调用useViewport时处于ViewportProvider范围内

自定义钩子useViewport依赖React上下文,必须在被ViewportProvider包裹的组件/钩子中调用:

  • 确认layout.tsx中ViewportProvider包裹了整个应用的根组件:
    // src/app/layout.tsx
    import { ViewportProvider } from '@/context/ViewportContext';
    
    export default function RootLayout({ children }) {
      return (
        <html lang="zh-CN">
          <body>
            <ViewportProvider>{children}</ViewportProvider>
          </body>
        </html>
      );
    }
    
  • 禁止在非React组件/钩子环境中调用useViewport(比如直接在utils文件的顶层代码执行),必须在组件渲染周期或自定义钩子内部调用。

3. 排查循环依赖问题

检查ViewportContext.tsx和useDeviceType.tsx是否存在互相导入的情况:

  • 如果ViewportContext中导入了useDeviceType,同时useDeviceType又导入了useViewport,会导致模块加载异常,出现导出未定义的错误。
  • 解决方式:重构代码,把共享逻辑抽离到独立文件,避免双向引用。

4. 验证TypeScript路径映射是否生效

虽然你已配置@/*映射,仍可再次确认:

  • 打开tsconfig.json,确保compilerOptions.paths配置正确:
    {
      "compilerOptions": {
        "baseUrl": ".",
        "paths": {
          "@/*": ["src/*"]
        }
      }
    }
    
  • 重启NextJS开发服务器,路径映射修改后通常需要重启才能生效。
  • 可尝试用相对路径导入测试(比如import { useViewport } from '../context/ViewportContext'),若能正常运行,说明路径映射配置存在问题。

5. 检查useViewport的定义是否合规

确认useViewport是标准的React自定义钩子:

  • 必须以use开头,内部只能调用React内置钩子(比如useContext):
    // 正确示例
    import { useContext } from 'react';
    import { ViewportContext } from './ViewportContext';
    
    export function useViewport() {
      const context = useContext(ViewportContext);
      if (!context) {
        throw new Error('useViewport must be used within a ViewportProvider');
      }
      return context;
    }
    
  • 如果useViewport错误导出了非函数值(比如对象、字符串),也会触发该错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 06:16:07