Gatsby构建react-tiktok报window未定义及懒加载报错求助
解决Gatsby中react-tiktok的SSR window未定义及组件挂起问题
问题根源
react-tiktok库的代码在模块导入阶段就直接调用了window.fetch,而Gatsby构建时的SSR(服务器端渲染)环境运行在Node.js中,不存在window对象,导致报错。之前添加的typeof window !== 'undefined'判断无效,是因为库的代码在你的组件逻辑执行前就已经加载执行了;使用React.lazy出现组件挂起错误,是因为React.lazy不支持SSR环境下的代码拆分。
解决方案1:使用@loadable/component实现SSR兼容的懒加载
这是Gatsby官方推荐的SSR友好代码拆分方案,具体步骤:
- 安装依赖:
npm install @loadable/component # 或者用yarn yarn add @loadable/component
- 创建一个封装的TikTok嵌入组件(比如
src/components/TiktokEmbed.js):
import loadable from '@loadable/component' // 仅在客户端加载react-tiktok组件,禁止SSR阶段加载 const LoadableTiktok = loadable(() => import('react-tiktok'), { ssr: false, fallback: <div>加载中...</div> // 可选:加载时的占位内容 }) export default function TiktokEmbed(props) { return <LoadableTiktok {...props} /> }
- 在你的页面或组件中直接使用这个封装后的组件:
import TiktokEmbed from '../components/TiktokEmbed' function MyPage() { return ( <div> <h1>我的TikTok视频</h1> <TiktokEmbed url="https://www.tiktok.com/@example/video/123456789" /> </div> ) } export default MyPage
解决方案2:自定义客户端渲染组件包裹react-tiktok
如果不想额外安装依赖,可以自己写一个仅在客户端渲染的高阶组件:
- 创建
src/components/OnlyOnClient.js:
import { useState, useEffect } from 'react' export default function OnlyOnClient({ children }) { const [isClient, setIsClient] = useState(false) useEffect(() => { // 仅在客户端挂载后才标记为可渲染 setIsClient(true) }, []) return isClient ? children : null // SSR阶段返回null,避免执行window相关代码 }
- 在页面中使用:
import { useState, useEffect } from 'react' import OnlyOnClient from '../components/OnlyOnClient' function MyPage() { // 延迟导入react-tiktok,确保仅在客户端执行 const [Tiktok, setTiktok] = useState(null) useEffect(() => { import('react-tiktok').then(module => { setTiktok(module.default) }) }, []) return ( <div> <h1>我的TikTok视频</h1> <OnlyOnClient> {Tiktok && <Tiktok url="https://www.tiktok.com/@example/video/123456789" />} </OnlyOnClient> </div> ) } export default MyPage
关键说明
- 两种方案核心都是让react-tiktok的代码仅在客户端环境加载执行,避开SSR阶段的Node.js环境。
- 方案1更简洁且符合Gatsby的最佳实践,推荐优先使用。
内容的提问来源于stack exchange,提问作者olorin viggo
相关产品推荐
相关产品推荐

