当前位置: 首页 > 知识库问答 >
问题:

从useEffect动态渲染样式表?

狄信然
2023-03-14

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

我的理解是,然后,useEffect将“看到”状态变化并启动。这就是我们加载新样式表的地方。应用正确加载初始样式表,切换按钮可以正常工作一次,但之后就不能正常工作。第一次更改后,它会删除所有样式。使用反应开发工具,看起来状态正在正确更新。我认为我对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;

共有1个答案

司马飞鸿
2023-03-14

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

当你需要一个css文件时,它会添加一个html标签到你的dom。

<link rel="stylesheet" type="text/css" href="/styles/overrides.css">

<code>require</code>添加另一个CSS文件并不能撤消已经发生的<code>resquire</code>-它仍然被添加到浏览器样式表中。您可以将其视为导入JS文件而不是渲染组件。

您最直接的选择是将两个文件都导入为字符串,然后在中应用所需的样式

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>
  );
}

带有实现的示例代码沙盒。

更可靠的方法是使用css变量,并使用设置属性的CSS类来重写它们。这将需要更多的工作来适应你的靴子样本主题。

:root {
  --primary: #FFFFFF;
}

.dark-theme {
  --primary: #000000;
}

此选项通过交换为每个样式定义的变量来避免重复样式。如果您选择此选项,您应该考虑浏览器支持,以及您是否可以在不受支持的浏览器上没有主题。

 类似资料:
  • 在Vue2环境中,有一个动态表单,数据源如下: 要实现的功能是:每个表单项根据其对象里的show来判断是否显示,如果show为空数组,代表无条件限制。 比如是否合格这一项,只有在 年龄<=28&&身高>=180 时才显示。 测试渲染代码如下: 请问下一步该如何进行?

  • 问题内容: 在React JSX中,似乎无法执行以下操作: 我收到一个解析错误:意外令牌{。这不是React可以处理的吗? 我正在设计此组件,以便在内部隐藏的值将包含有效的HTML元素(h1,p等)。有什么办法可以使这项工作吗? 问题答案: 您不应该将组件子弹放在花括号中: 这是一个有效的小提琴:http : //jsfiddle.net/kb3gN/6668/ 此外,您还可以找到JSX编译器,有

  • 因此,我试图用几个HTML输入创建一个动态表单。我有一个对象数组,其中包含应该呈现的的。目前,我能够呈现两个输入,如文本区域,但我如何处理收音机,复选框,选择连同他们的选项?任何帮助都将不胜感激。 请参见此CodeSandBox。

  • 服务端动态渲染网页是生成网页的最常用方法, 该方法同样适用于动态生成包含 Highcharts 图表的网页。 服务端动态渲染网页的做法:后端程序读取数据库数据并按照一定的业务逻辑处理成字符串,在页面对应位置上输出。 下面我们用 PHP 举例简单说明这个过程: 实例1: 只包含数值的 <?php // php 读取数据库并生成 字符串,这里这是简单的实例 // 读取数据 while ($

  • 问题内容: 如何在样式组件中使用条件渲染以使用React中的样式组件将按钮类设置为活动状态? 在css中,我会这样做: 在样式化的组件中,如果我尝试在类名中使用“ &&”,则不喜欢它。 问题答案: 你可以简单地做到这一点 在您的样式中,如下所示:

  • 对于 vue-server-renderer 的基本 renderer 和 bundle renderer 都提供开箱即用的流式渲染功能。所有你需要做的就是,用 renderToStream 替代 renderToString: const stream = renderer.renderToStream(context) 返回的值是 Node.js stream: let html = ''