Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/css/34.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 从useEffect动态渲染样式表?_Javascript_Css_Reactjs_React Hooks - Fatal编程技术网

Javascript 从useEffect动态渲染样式表?

Javascript 从useEffect动态渲染样式表?,javascript,css,reactjs,react-hooks,Javascript,Css,Reactjs,React Hooks,我试图使用一个按钮(传递给另一个组件)来切换暗模式。最初,我加载一个轻量级主题样式表。然后,“切换主题”按钮应删除页面上最新加载的样式表,并将状态设置为与当前状态相反的状态 我的理解是,然后,useEffect将“看到”状态变化并开始生效。这就是我们加载新样式表的地方。应用程序会正确加载初始样式表,切换按钮会正确工作一次,但之后不会。第一次更改后,它将删除所有样式。使用react-dev工具,状态似乎正在正确更新。我认为我对useEffect和/或useState的理解是错误的。感谢您的指点和帮

我试图使用一个按钮(传递给另一个组件)来切换暗模式。最初,我加载一个轻量级主题样式表。然后,“切换主题”按钮应删除页面上最新加载的样式表,并将状态设置为与当前状态相反的状态

我的理解是,然后,useEffect将“看到”状态变化并开始生效。这就是我们加载新样式表的地方。应用程序会正确加载初始样式表,切换按钮会正确工作一次,但之后不会。第一次更改后,它将删除所有样式。使用react-dev工具,状态似乎正在正确更新。我认为我对useEffect和/或useState的理解是错误的。感谢您的指点和帮助

import { useState, useEffect } from "react";
import Navi from "./Components/Layout/Navi";
import Price from "./Components/Price";
import { BrowserRouter as Router, Route } from "react-router-dom";
import { Container } from "react-bootstrap";
import About from "./Components/About/About";
require("bootswatch/dist/cosmo/bootstrap.min.css");

function App() {
    const [theme, setTheme] = useState("light");
    const toggleTheme = () => {
        Array.from(document.getElementsByTagName("style")).slice(-1)[0].remove();
        setTheme(theme === "dark" ? "light" : "dark");
    };
    useEffect(() => {
        console.log("fire");
        console.log(theme);
        if (theme === "light") {
            require("bootswatch/dist/cosmo/bootstrap.min.css");
        } else if (theme === "dark") {
            require("bootswatch/dist/slate/bootstrap.min.css");
        } else {
            console.log("Theme state not correctly set");
        }
    });
    return (
        <Router path="/">
            <>
                <div className="App">
                    <Navi toggleTheme={() => toggleTheme()} />
                    <Container>
                        <Route path="/" exact component={Price} />
                        <Route path="/about" exact component={About} />
                    </Container>
                </div>
            </>
        </Router>
    );
}

export default App;

从“react”导入{useState,useffect};
从“/Components/Layout/Navi”导入Navi;
进口价格来自“/部件/价格”;
从“react Router dom”导入{BrowserRouter as Router,Route};
从“react bootstrap”导入{Container};
从“/Components/About/About”导入关于;
要求(“bootswatch/dist/cosmo/bootstrap.min.css”);
函数App(){
const[theme,setTheme]=useState(“光”);
常量切换主题=()=>{
数组.from(document.getElementsByTagName(“样式”)).slice(-1)[0].remove();
setTheme(theme==“暗”?“亮”:“暗”);
};
useffect(()=>{
控制台日志(“火灾”);
console.log(主题);
如果(主题==“光”){
要求(“bootswatch/dist/cosmo/bootstrap.min.css”);
}else if(主题==“暗”){
要求(“bootswatch/dist/slate/bootstrap.min.css”);
}否则{
console.log(“主题状态设置不正确”);
}
});
返回(
toggleTheme()}/>
);
}
导出默认应用程序;

您对
useffect
的理解似乎是准确的。他们在你期望的时候执行。没有像您预期的那样发生的是
导入

当您
需要
css文件时,它会向dom添加
html
标记


require
ing另一个CSS文件不会撤消已发生的
require
——它仍将添加到浏览器样式表中。您可以将其视为导入JS文件而不是呈现组件

选项1:添加您自己的
标记 最直接的选择是将两个文件作为字符串导入,然后在
标记中应用所需的样式。这是一个“快速简单”的选项,但包含一些折衷(例如,不管怎样,您都要在捆绑包的样式中导入两个主题)

此选项通过交换为每个样式定义的变量来避免重复样式。如果你选择了这个选项,你应该考虑一下,在没有支持的浏览器上是否没有主题。
import React, { useState } from "react";
// using inline webpack loaders for convenience of the example in Code Sandbox
import mainCSS from "!!raw-loader!./styles.css";
import altCSS from "!!raw-loader!./altstyles.css";
// Using helmet to bring the styles into the head (not necessary)
import { Helmet } from "react-helmet";

console.log(mainCSS);
export default function App() {
  const [showAltStyles, setShowAltStyles] = useState(false);
  return (
    <div className="App">
      <Helmet>
        <style>{showAltStyles ? altCSS : mainCSS}</style>
      </Helmet>
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <button onClick={() => setShowAltStyles(!showAltStyles)}>
        Toggle Alt Styles
      </button>
    </div>
  );
}