Reactjs WebPackageError:ReferenceError:未定义文档-netlify生成

Reactjs WebPackageError:ReferenceError:未定义文档-netlify生成,reactjs,build,gatsby,Reactjs,Build,Gatsby,我在netlify上构建项目时出错(WebPackageError:ReferenceError:document未定义)。在开发工作中表现出色 我看到用JSDOM解决这个问题是可能的,但我已经尝试过了,但我无法使它正确 import React from "react"; import "../css/DarkMode.css"; const DarkMode = () => { let clicked

我在netlify上构建项目时出错(WebPackageError:ReferenceError:document未定义)。在开发工作中表现出色

我看到用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;
从“React”导入React;
导入“./css/DarkMode.css”;
常数暗模式=()=>{
让clickedClass=“单击”;
const body=document.body;
const lightTheme=“light”;
const darkTheme=“黑暗”;
让主题;
if(本地存储){
theme=localStorage.getItem(“主题”);
}
如果(主题===光主题| |主题===暗主题){
body.classList.add(主题);
}否则{
body.classList.add(lightTheme);
}
const switchTheme=(e)=>{
如果(主题===暗主题){
body.classList.replace(暗主题、光主题);
e、 target.classList.remove(单击类);
setItem(“主题”、“灯光”);
主题=轻主题;
}否则{
body.classList.replace(lightTheme,darkTheme);
e、 target.classList.add(点击class);
setItem(“主题”、“暗”);
主题=黑暗主题;
}
};
返回(
切换主题(e)}
>
);
};
导出默认暗模式;

您想实现主题切换的想法完全错误

  • React使用虚拟DOM而不是真实的DOM。(虚拟DOM是HTML树的对象版本) 这就是为什么在页面初始化之前不定义文档的原因。如果您想获取文档,最好在
    useffect()
    hook中使用它。(第一页之后)
  • 在您的情况下,您有很多选择来实现多主题,我建议您使用样式化组件
  • 扩展:

    这与它本身无关。如前所述,使用React,您正在创建和操作一个虚拟DOM(vDOM),使用代码片段,您直接指向真实的DOM(
    document.body
    等等)。此外,这些操作大大降低了代码/应用程序的性能,因为它们会给浏览器带来巨大的成本,这就是React如此之快的原因(除其他外)

    在React应用程序中操纵真实DOM可能会导致严重的警告和警告,可能会阻止(按需刷新/重新呈现新内容)

    总之,您的代码在
    gatsby develope
    下工作,而不是在
    gatsby build
    下工作,因为
    gatsby develope
    由浏览器处理
    gatsby build
    id在节点服务器中编译,其中显然没有
    窗口
    文档
    ,因为它们甚至还没有创建

    简单的解决方法是在以下情况下包装代码(使用全局对象):

    if (typeof window !== `undefined`) { // or typeof document !== 'undefined'
      // your code that uses global objects here
    }
    
    但正如我所说,它可能会阻止水化反应

    要在盖茨比中添加主题,您可以选择使用插件()或使用基于React的方法

    有用资源:


    谢谢你,伙计!我已经尝试使用盖茨比插件黑暗模式,但它有一个功能,我不喜欢,如果你在你的bowser默认有暗模式,它会自动改变页面到暗模式,我不喜欢,我想有一个按钮打开和关闭,但谢谢。我肯定会尝试一种基于React的方法。谢谢你,伙计