Next.js中Spinner与Link组件无法作为JSX组件使用的问题
在Next.js项目中,Parent组件使用Spinner和Next.js原生Link组件时抛出类型不兼容错误,但Spinner组件本身无报错。
组件代码
Spinner.tsx
export default function Spinner() { return ( <div className='flex justify-center items-center w-[5%] m-auto'> <img src='/asset/kolici-yukleniyor.gif' alt="loading..." className='w-full' /> </div> ) }
Parent.tsx
import Link from "next/link"; import Spinner from "./Spinner"; export default function AllPosts({ posts }: any) { let loading = true; let error = false; if (posts) { loading = false; error = false; } else { error = true; } return ( <div className="responsive-layout"> <div className="text-black py-8"> {loading ? ( <Spinner /> ) : error ? ( <div className="flex items-center justify-center h-[50vh]"> <p className="text-center text-base flex justify-center gap-2 items-center"> An error occurred. Please refresh your browser </p> </div> ) : ( <div className="grid md:grid-cols-3 gap-4"> {posts.nodes.map((post: Post, i: number) => ( <Link key={i} className="card-link" href={`/blog/${post.slug}`}> <div className="card" key={i}> <div className="card-body" key={i}> <h3 className="card-title">{post.title}</h3> </div> </div> </Link> ))} </div> )} </div> </div> ); }
错误信息
Spinner组件错误
'Spinner' cannot be used as a JSX component.
Its type '() => Element' is not a valid JSX element type.
Type '() => Element' is not assignable to type '(props: any, deprecatedLegacyContext?: any) => ReactNode'.
Type 'Element' is not assignable to type 'ReactNode'.
Property 'children' is missing in type 'Element' but required in type 'ReactPortal'.
Link组件错误
'Link' cannot be used as a JSX component.
Its type 'ForwardRefExoticComponent<Omit<AnchorHTMLAttributes, keyof InternalLinkProps> & InternalLinkProps & { ...; } & RefAttributes<...>>' is not a valid JSX element type.
项目依赖版本
{ "next": "12", "react": "18.2.0", "react-dom": "18.2.0", "typescript": "4.1.2" }
1. 升级TypeScript版本
TypeScript 4.1.2对React 18的类型支持不完善,需升级到4.6.4及以上版本(推荐4.9+,兼容React 18和Next.js 12):
npm install typescript@^4.9.5 --save-dev # 或使用yarn yarn add typescript@^4.9.5 --dev
2. 匹配React与Next.js版本(可选但推荐)
Next.js 12原生适配React 17,和React 18存在兼容性问题:
- 若保留Next.js 12,降级React到17.x版本:
npm install react@^17.0.2 react-dom@^17.0.2 # 或使用yarn yarn add react@^17.0.2 react-dom@^17.0.2
- 若保留React 18,升级Next.js到13.x版本(官方支持React 18):
npm install next@^13.4.0 # 或使用yarn yarn add next@^13.4.0
3. 修复TypeScript配置
调整tsconfig.json,确保适配Next.js和React类型:
{ "compilerOptions": { "target": "es5", "lib": ["dom", "dom.iterable", "esnext"], "allowJs": true, "skipLibCheck": true, "strict": true, "forceConsistentCasingInFileNames": true, "noEmit": true, "esModuleInterop": true, "module": "esnext", "moduleResolution": "node", "resolveJsonModule": true, "isolatedModules": true, "jsx": "preserve", "incremental": true, "types": ["react", "react-dom"] }, "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], "exclude": ["node_modules"] }
4. 清除缓存并重启服务
# 清除Next.js缓存 rm -rf .next # 若问题仍存在,清除依赖后重新安装 rm -rf node_modules package-lock.json npm install # 重启开发服务 npm run dev
额外优化:补充Parent组件类型定义
避免any类型和未定义的Post类型,补充类型声明:
interface Post { slug: string; title: string; // 根据实际字段补充其他属性 } interface AllPostsProps { posts: { nodes: Post[] } | null; } export default function AllPosts({ posts }: AllPostsProps) { // 原有逻辑 }
内容的提问来源于stack exchange,提问作者blossom-babs

