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
相关产品推荐
相关产品推荐

