[英]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:
const themeMode = themes.light
with const [themeMode, setThemeMode] = useState(themes.light);
const themeMode = themes.light
替换为const [themeMode, setThemeMode] = useState(themes.light);
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 中不需要同时使用
darkMode
和themeMode
,因为其中一个只是从另一个计算得出的。 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.