[英]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 中不需要同时使用darkMode
和themeMode
,因为其中一个只是从另一个计算得出的。 如果您只使用一个 state 变量,您也不需要useEffect
来根据另一个自动更新一个。 但我会让您解决这些问题 - 我希望这至少能帮助您入门!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.