Vitepress中使用外部React库构建后报错:Cannot read 'useRef' of null
解决Vitepress中Shoelace React组件构建后
useRef报错问题 问题原因
Vitepress默认执行服务端渲染(SSR),而Shoelace的React封装依赖浏览器DOM环境,SSR阶段缺少window等浏览器对象,导致React的useRef等hooks无法正常初始化,最终抛出Uncaught TypeError: Cannot read properties of null (reading 'useRef')错误。
可行解决方案
1. 动态导入时禁用SSR
在组件中通过动态导入加载Shoelace组件,同时添加{ ssr: false }标记,强制代码仅在客户端执行:
import { defineComponent, onMounted, ref } from 'vue' export default defineComponent({ setup() { const SlButton = ref(null) onMounted(async () => { // 仅客户端加载Shoelace组件 const component = await import('@shoelace-style/shoelace/dist/react', { ssr: false }) SlButton.value = component.SlButton }) return () => SlButton.value ? <SlButton.value variant="primary">测试按钮</SlButton.value> : null } })
2. 隔离客户端组件+ClientOnly包裹
创建仅客户端执行的组件文件(比如命名为ShoelaceComponent.client.jsx),将Shoelace的导入和渲染逻辑放在其中:
// 该文件仅在客户端运行 import { SlButton, SlCard } from '@shoelace-style/shoelace/dist/react' export default function ShoelaceDemo() { return ( <SlCard> <SlButton variant="success">客户端渲染按钮</SlButton> </SlCard> ) }
在Markdown文档中用Vitepress的ClientOnly组件包裹使用:
<ClientOnly> <ShoelaceDemo /> </ClientOnly>
3. 全局配置SSR排除Shoelace依赖
在.vitepress/config.ts中,通过Vite的SSR配置将Shoelace排除在服务端渲染流程外:
import { defineConfig } from 'vitepress' import react from '@vitejs/plugin-react' export default defineConfig({ vite: { plugins: [react()], ssr: { // 让Shoelace相关包跳过SSR处理 external: ['@shoelace-style/shoelace'] } }, // 其他Vitepress配置... })
4. 主题中延迟加载Shoelace资源
在.vitepress/theme/index.ts中,利用onClientMounted钩子在客户端初始化Shoelace的样式和脚本:
import DefaultTheme from 'vitepress/theme' import { onClientMounted } from 'vitepress' export default { ...DefaultTheme, setup() { onClientMounted(async () => { // 客户端加载时才引入Shoelace样式和核心脚本 await import('@shoelace-style/shoelace/dist/themes/light.css') import('@shoelace-style/shoelace/dist/shoelace.js') }) } }
注意事项
- 避免在组件顶部直接导入Shoelace组件,即使有
ClientOnly包裹,SSR阶段仍会解析导入语句导致报错; - 动态导入时必须添加
{ ssr: false },否则Vite仍会尝试在SSR阶段处理该模块。
内容的提问来源于stack exchange,提问作者Anurag Gupta
相关产品推荐
相关产品推荐

