Next.js App Router中navigator未定义:原因及解决方法
问题原因
就算组件加了"use client",Next.js在服务器端渲染(SSR)或静态生成(SSG)阶段,还是会对客户端组件的代码做语法解析和初步执行。navigator是浏览器独有的全局对象,服务器环境里根本没有这个变量,直接写navigator会触发引用错误,所以终端会报错。而浏览器里能正常运行,是因为到了客户端环境后navigator存在,判断逻辑能正常走通。
解决方法
有两种靠谱的修复方式:
方式一:用typeof做安全判断
把直接访问navigator的判断改成typeof navigator !== 'undefined'——服务器端执行typeof navigator只会返回'undefined',不会触发报错:
{typeof navigator !== 'undefined' && navigator?.share && ( <button className="absolute top-6 right-16" onClick={() => { navigator .share({ title: 'Title: ' + article.title, url: 'http://localhost:3000/articles/' + article.id, }) .then(() => console.log('Successful share')) .catch(() => console.log('Error sharing')); }} > <Image src={Share} className="w-6 h-6" alt={'Share Icon'} /> </button> )}
方式二:用useState+useEffect延迟检测
利用React的useEffect只在客户端执行的特性,组件挂载后再检测navigator.share是否存在,通过状态控制按钮渲染:
'use client'; import { useState, useEffect } from 'react'; // 组件内部逻辑 const [canShare, setCanShare] = useState(false); useEffect(() => { // 客户端环境才会执行这里的代码 setCanShare(!!(navigator?.share)); }, []); // 渲染按钮部分 {canShare && ( <button className="absolute top-6 right-16" onClick={() => { navigator .share({ title: 'Title: ' + article.title, url: 'http://localhost:3000/articles/' + article.id, }) .then(() => console.log('Successful share')) .catch(() => console.log('Error sharing')); }} > <Image src={Share} className="w-6 h-6" alt={'Share Icon'} /> </button> )}
内容的提问来源于stack exchange,提问作者user22619342
相关产品推荐
相关产品推荐

