Next.js报错ReferenceError: window is not defined,求解决方案
修复Next.js中"window is not defined"错误
错误原因
Next.js采用服务端渲染(SSR)机制,在服务端执行组件渲染流程时,浏览器环境的window对象并不存在。你的组件在返回JSX时直接访问window.location.origin,导致服务端渲染阶段抛出ReferenceError。
修复方案
方案1:直接使用public目录资源路径(推荐)
你的天气图标存放在public/weather-icons目录下,Next.js会自动将public目录内的资源映射到网站根路径,因此无需拼接window.location.origin,直接使用根相对路径即可:
function IconWeatherComponent({icon}) { let [svg, setSvg] = useState(''); useEffect(() => { const setIcon = () => { if (icon === '01d') { setSvg('day.svg') } if (icon === '01n') { setSvg('night.svg') } } setIcon(); }, [icon]) return ( <div> {/* 仅当svg有值时渲染图片,避免初始状态请求无效路径 */} {svg && <img src={`/weather-icons/${svg}`} width="70" height="70" alt="weather icon"/>} </div> ); } export default IconWeatherComponent
方案2:在客户端环境下获取window对象
如果确实需要使用window.location.origin,可以利用useEffect在组件挂载后(此时已处于客户端环境)设置完整路径:
function IconWeatherComponent({icon}) { let [iconSrc, setIconSrc] = useState(''); useEffect(() => { const setIcon = () => { let iconName = ''; if (icon === '01d') { iconName = 'day.svg' } else if (icon === '01n') { iconName = 'night.svg' } // 客户端环境下window对象已存在 setIconSrc(`${window.location.origin}/weather-icons/${iconName}`); } setIcon(); }, [icon]) return ( <div> {iconSrc && <img src={iconSrc} width="70" height="70" alt="weather icon"/>} </div> ); } export default IconWeatherComponent
方案3:标记组件为仅客户端渲染
通过Next.js的动态导入功能,将组件设置为仅在客户端渲染,彻底规避服务端渲染时的window问题:
// 在父组件中动态导入IconWeatherComponent import dynamic from 'next/dynamic'; const IconWeatherComponent = dynamic( () => import('./IconWeatherComponent'), { ssr: false } );
注:此方法会牺牲服务端渲染带来的性能优势,仅在组件无需SSR时使用。
内容的提问来源于stack exchange,提问作者SelimSezer
相关产品推荐
相关产品推荐

