简体   繁体   English

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

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

I have some trouble implementing multiple color themes into my website.我在我的网站中实施多个颜色主题时遇到了一些麻烦。 I have made a button connected to a state toggle, and every time the state switches, a useEffect handler sets the value of my context.provider to dark/light theme.我制作了一个连接到 state 开关的按钮,每次 state 切换时,useEffect 处理程序都会将我的 context.provider 的值设置为深色/浅色主题。 When I log the useEffect handler it changes the theme, however the child components are not affected by it.当我记录 useEffect 处理程序时,它会更改主题,但是子组件不受它的影响。

This is my App.tsx:这是我的 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;

And this is one of my components that should use the updated theme:这是我应该使用更新主题的组件之一:

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

You have const themeMode = themes.light;你有const themeMode = themes.light; in your component.在你的组件中。 This does exactly what it says: sets the themeMode variable to be the constant themes.light .这正是它所说的:将themeMode变量设置为常量themes.light

When you attempt (I presume) to "change it" in the event handler, you're doing const themeMode = darkmode? themes.light: themes.dark;当您尝试(我假设)在事件处理程序中“更改它”时,您正在执行const themeMode = darkmode? themes.light: themes.dark; const themeMode = darkmode? themes.light: themes.dark; , but with nothing else in that function (other than a console.log ) - as this variable is only scoped to that one function, it does not change the same-named variable outside. ,但在 function 中没有其他内容(除了console.log )——因为这个变量的范围仅限于那个 function,它不会在外部更改同名变量。

Even if you made it change the outer variable (by declaring the outer variable with let instead of const and not shadowing the variable inside the function but updating its value), that won't work at all well with React.即使你让它改变了外部变量(通过用let而不是const声明外部变量并且不隐藏 function 中的变量而是更新它的值),这在 React 中也不会很好地工作。

The solution is to use state instead:解决方案是改用 state:

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

Making the above 2 changes will work - but you can still simplify your component quite a lot.进行上述 2 项更改将起作用 - 但您仍然可以大大简化您的组件。 You don't need both darkMode and themeMode in state, as one is simply calculated from the other.在 state 中不需要同时使用darkModethemeMode ,因为其中一个只是从另一个计算得出的。 If you just use one state variable you also won't need a useEffect to automatically update one based on the other.如果您只使用一个 state 变量,您也不需要useEffect来根据另一个自动更新一个。 But I'll leave you to sort out those problems - I hope this helps you get started, at least!但我会让您解决这些问题 - 我希望这至少能帮助您入门!

暂无
暂无

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

相关问题 React context.provider不会更改默认值 - React context.provider doesn't change the default value 用它包装我的应用程序组件时 Context.provider 抛出错误 - Context.provider throw error when wrapping my app component with it 当提供程序组件父状态更改时,为什么无法更新子组件中的值(使用react上下文)? - Why can't update a value in a child component (with react context) when a provider component parent state change? 挂钩更改 state 不会更新上下文提供程序的值? - hook change state doesn't update context provider's value? 如何访问react Context.Provider值内的另一个函数? - How can I access another function inside the react Context.Provider value? 在 React 中将多个值和设置器对传递给 Context.Provider - Passing multiple value and setter pairs to Context.Provider in React 我正在尝试使用挂钩来管理Context.Provider的状态 - I am attempting to use hooks to manage the state of Context.Provider 为什么 React Context.Provider 是必需的(或有用的)? - Why Is React Context.Provider Necessary (Or useful)? React Native Context - 从渲染之外的 Context.provider 中检索值 function - React Native Context - retrieve the value from Context.provider outside of the render function 当上下文更改时,使用上下文的子组件是否应该自动更新? - Shouldn't child components that use context update themselves automatically when context gets changed?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM