繁体   English   中英

当我更新 context.provider 的值时,子组件不会改变颜色

[英]When I update my context.provider's value, the child components don't change color

我在我的网站中实施多个颜色主题时遇到了一些麻烦。 我制作了一个连接到 state 开关的按钮,每次 state 切换时,useEffect 处理程序都会将我的 context.provider 的值设置为深色/浅色主题。 当我记录 useEffect 处理程序时,它会更改主题,但是子组件不受它的影响。

这是我的 App.tsx:

import {
  useContext,
  useState,
  Provider,
  createContext,
  useEffect,
} from "react";
import logo from "./logo.svg";
import "./App.scss";
import Nav from "./components/ui/nav/Nav";
import Welcome from "./components/ui/welcome/Welcome";
import Section from "./components/ux/section/Section";
import Prices from "./components/ui/prices/Prices";
import { themes, ThemeContext } from "./components/theme/theme";
import Background from "./components/ui/background/Background";

function App() {
  const theme = useContext(ThemeContext);
  const [darkmode, setdarkmode] = useState(true);
  const themeMode = themes.light;
  useEffect(() => {
    const themeMode = darkmode ? themes.light : themes.dark;
    console.log(themeMode);
  }, [darkmode]);

  document.body.style.background = theme.primary;
  document.body.style.color = theme.text;
  return (
    <ThemeContext.Provider value={themeMode}>
      <button
        onClick={() => {
          setdarkmode(!darkmode);
        }}
      >
        hello
      </button>
      <Background />

      <Section content={<Welcome />} />
      <Section content={<Prices />} />
    </ThemeContext.Provider>
  );
}

export default App;

这是我应该使用更新主题的组件之一:

import React, { useContext, useState } from "react";
import "./button.scss";
import { themes, ThemeContext } from "../../theme/theme";
export default function Button(props: {
  invert: boolean;
  link: string | URL;
  content: string;
}) {
  var style = {};

  const theme = useContext(ThemeContext);
  const buttonStyle = {
    color: theme.primary,
    background: theme.cta,
    border: "solid 2px " + theme.cta,
  };
  const invertStyle = {
    color: theme.cta,
    background: theme.primary,
    border: "solid 2px " + theme.cta,
  };

  props.invert ? (style = invertStyle) : (style = buttonStyle);
  const [colorStyle, setColorStyle] = useState(false);
  colorStyle
    ? props.invert
      ? (style = buttonStyle)
      : (style = invertStyle)
    : props.invert
    ? (style = invertStyle)
    : (style = buttonStyle);
  return (
    <button
      onClick={() => {
        window.location.assign(props.link);
      }}
      onMouseEnter={() => {
        setColorStyle(!colorStyle);
      }}
      onMouseLeave={() => {
        setColorStyle(!colorStyle);
      }}
      className="ux-btn"
      style={style}
    >
      {props.content}
    </button>
  );
}

你有const themeMode = themes.light; 在你的组件中。 这正是它所说的:将themeMode变量设置为常量themes.light

当您尝试(我假设)在事件处理程序中“更改它”时,您正在执行const themeMode = darkmode? themes.light: themes.dark; const themeMode = darkmode? themes.light: themes.dark; ,但在 function 中没有其他内容(除了console.log )——因为这个变量的范围仅限于那个 function,它不会在外部更改同名变量。

即使你让它改变了外部变量(通过用let而不是const声明外部变量并且不隐藏 function 中的变量而是更新它的值),这在 React 中也不会很好地工作。

解决方案是改用 state:

  • const themeMode = themes.light替换为const [themeMode, setThemeMode] = useState(themes.light);
  • 在事件处理程序中,替换const themeMode = darkmode? themes.light: themes.dark; const themeMode = darkmode? themes.light: themes.dark; setThemeMode(darkmode? themes.light: themes.dark);

进行上述 2 项更改将起作用 - 但您仍然可以大大简化您的组件。 在 state 中不需要同时使用darkModethemeMode ,因为其中一个只是从另一个计算得出的。 如果您只使用一个 state 变量,您也不需要useEffect来根据另一个自动更新一个。 但我会让您解决这些问题 - 我希望这至少能帮助您入门!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM