我在 netlify 上构建我的项目时遇到错误(WebpackError: ReferenceError: document is not defined)。在开发中工作正常!
我看到可以用 JSDOM 解决这个问题,但我已经尝试过,但我无法做到。
import React from "react";
import "../css/DarkMode.css";
const DarkMode = () => {
let clickedClass = "clicked";
const body = document.body;
const lightTheme = "light";
const darkTheme = "dark";
let theme;
if (localStorage) {
theme = localStorage.getItem("theme");
}
if (theme === lightTheme || theme === darkTheme) {
body.classList.add(theme);
} else {
body.classList.add(lightTheme);
}
const switchTheme = (e) => {
if (theme === darkTheme) {
body.classList.replace(darkTheme, lightTheme);
e.target.classList.remove(clickedClass);
localStorage.setItem("theme", "light");
theme = lightTheme;
} else {
body.classList.replace(lightTheme, darkTheme);
e.target.classList.add(clickedClass);
localStorage.setItem("theme", "dark");
theme = darkTheme;
}
};
return (
<button
className={theme === "dark" ? clickedClass : ""}
id="darkMode"
className={"btnDarkMode"}
onClick={(e) => switchTheme(e)}
></button>
);
};
export default DarkMode;
答案 0 :(得分:1)
你想实现主题切换完全错误。
useEffect()
钩子中使用它。 (在页面初始化之后)答案 1 :(得分:1)
这与jsdom
本身无关。如前所述,使用 React,您正在创建和操作虚拟 DOM (vDOM),而使用您的代码段,您直接指向真实 DOM(document.body
等)。此外,这些操作会极大地降低代码/应用程序的性能,因为它们会给浏览器带来巨大的成本,这就是 React 如此之快的原因(除其他外)。
在 React 应用程序中操作真实 DOM 可能会导致严重的警告和警告,可能会阻止 hydration of React(按需刷新/重新呈现新内容)。
总结一下,您的代码在 gatsby develop
下而不是 gatsby build
下工作的事实是,因为 gatsby develop
由浏览器 where there are global objects (such as window
or document
) 处理。 gatsby build
id 在 Node 服务器中编译,其中显然没有 window
或 document
,因为它们甚至还没有被创建。
简单的解决方法是在这种情况下包装您的代码(您使用全局对象的地方):
if (typeof window !== `undefined`) { // or typeof document !== 'undefined'
// your code that uses global objects here
}
但正如我所说,它可能会阻止 React 的水合作用。
要在 Gatsby 中添加主题,您有很多选择,例如使用插件 (gatsby-plugin-dark-mode
) 或使用基于 React 的方法。
有用的资源: