Next.Js 应用程序路由器中未定义 Navigator

问题描述 投票:0回答:2

我的组件中有这段代码,顶部标有“使用客户端”。

在我的回报中,我有一个按钮。我询问导航器共享是否可用,然后会显示。我这样做是因为并非所有浏览器都支持 Web Share API。它也工作得很好。在 Chrome 中,我看到共享按钮并且它可以工作。例如,在 FIrefox 中我没有看到它(因为不支持它)。在浏览器控制台中也没有错误。

但是,在我的 VSCode 终端中,我总是收到 ReferenceError: navigator is not Defined。
为什么?我怎样才能摆脱它?

我的 page.tsx 中的一段代码,标记为“使用客户端”:
我在其他地方都没有使用导航器,所以这是我的终端中错误的根源,但它实际上可以工作。

            {navigator && 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>
            )}
javascript reactjs typescript next.js navigator
2个回答
0
投票

解决这个问题的方法是你必须先检查代码是否在服务器/客户端中运行,

所以你需要像下面那样做

    {typeof window !== 'undefined' && navigator && 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>
            )}

至于为什么当你已经有“使用客户端”时还需要这个,客户端组件实际上与下一页相同,该组件将在服务器和客户端上运行

这就是您的服务器日志中出现导航器错误的原因。


0
投票

标有“use client”指令的页面仍然是服务器端渲染(SSR),因此如果您使用浏览器 API,您将看到未定义的错误。您可以使用

next/dynamic
禁用 SSR,如下所示:

import dynamic from "next/dynamic";

const ClientComponent = dynamic(
  () => import("./components/ClientComponent"),
  { ssr: false }
);

const App = () => {
  return (
    <>
      <ClientComponent />
    </>
  )
}
© www.soinside.com 2019 - 2024. All rights reserved.