Next.js13中使用prism-react-renderer与markdown-to-jsx时useState报错
问题原因及解决方法
核心原因分析
你遇到的(0 , import_react.useState) is not a function or its return value is not iterable错误,主要和Next.js 13的React Server Components(RSC)机制直接相关,其次可能涉及依赖版本或缓存问题:
- RSC限制:Next.js 13 App Router下的组件默认是服务端组件,服务端组件不允许使用任何React Hooks(包括
useState),而prism-react-renderer内部依赖Hooks实现高亮逻辑,直接在服务端组件中使用会触发报错。 - 依赖版本/缓存问题:即便官方示例同版本,本地依赖安装可能存在版本不一致,或pnpm/Next.js的缓存残留导致旧代码未更新。
具体解决步骤
1. 标记组件为客户端组件
在使用prism-react-renderer或包含Hooks的页面/组件顶部,添加'use client'指令,将其转为客户端组件:
'use client'; // 必须放在文件最顶部 import React from 'react'; import Markdown from 'markdown-to-jsx'; import { Prism as SyntaxHighlighter } from 'prism-react-renderer'; import nightOwl from 'prism-react-renderer/themes/nightOwl'; // 自定义代码高亮组件 const CodeBlock = ({ children, className }: { children: string; className?: string }) => { const lang = className?.replace('language-', '') || 'javascript'; return ( <SyntaxHighlighter code={children.trim()} language={lang} theme={nightOwl}> {({ className, style, tokens, getLineProps, getTokenProps }) => ( <pre className={className} style={{ ...style, padding: '1rem', borderRadius: '8px' }}> {tokens.map((line, i) => ( <div {...getLineProps({ line, key: i })}> {line.map((token, key) => ( <span {...getTokenProps({ token, key })} /> ))} </div> ))} </pre> )} </SyntaxHighlighter> ); }; export default function MarkdownPage() { const markdown = ` # 代码高亮示例 \`\`\`typescript const greet = (name: string) => { console.log(\`Hello \${name}!\`); }; \`\`\` `; return ( <div className="p-8 max-w-3xl mx-auto"> <Markdown options={{ overrides: { code: { component: CodeBlock }, }, }} > {markdown} </Markdown> </div> ); }
2. 统一依赖版本并重装
如果上述操作后仍报错,删除本地依赖缓存并同步官方示例的依赖版本:
- 删除
node_modules和pnpm-lock.yaml:rm -rf node_modules pnpm-lock.yaml - 将官方示例
package.json中相关依赖版本复制到你的项目中,示例版本参考:{ "dependencies": { "next": "^13.4.19", "react": "^18.2.0", "react-dom": "^18.2.0", "markdown-to-jsx": "^7.2.1", "prism-react-renderer": "^1.3.5" } } - 重新安装依赖:
pnpm install
3. 清除Next.js缓存
删除.next文件夹后重启开发服务,避免缓存残留导致的代码不一致:
rm -rf .next pnpm run dev
内容的提问来源于stack exchange,提问作者Zhang Mathias
相关产品推荐
相关产品推荐

