当我更新 context.provider 的值时,子组件不会改变颜色
When I update my context.provider's value, the child components don't change color
我在我的网站中实施多个颜色主题时遇到了一些问题。我做了一个连接到状态切换的按钮,每次状态切换时,useEffect 处理程序都会将我的 context.provider 的值设置为 dark/light 主题。当我记录 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;
,但该函数中没有其他任何东西(除了 console.log
)-由于此变量仅适用于该函数,因此它不会更改外部的 same-named 变量。
即使你让它改变了外部变量(通过用 let
而不是 const
声明外部变量并且不隐藏函数内部的变量而是更新它的值),那不会'不能很好地与 React 一起工作。
解决方案是改用状态:
- 将
const themeMode = themes.light
替换为const [themeMode, setThemeMode] = useState(themes.light);
- 在事件处理程序中,将
const themeMode = darkmode ? themes.light : themes.dark;
替换为 setThemeMode(darkmode ? themes.light : themes.dark);
进行上述 2 项更改会奏效 - 但您仍然可以大大简化您的组件。您不需要状态中的 darkMode
和 themeMode
,因为一个只是从另一个计算得出的。如果你只使用一个状态变量,你也不需要 useEffect
来根据另一个自动更新一个。但我会让您解决这些问题 - 我希望这至少能帮助您入门!
我在我的网站中实施多个颜色主题时遇到了一些问题。我做了一个连接到状态切换的按钮,每次状态切换时,useEffect 处理程序都会将我的 context.provider 的值设置为 dark/light 主题。当我记录 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;
,但该函数中没有其他任何东西(除了 console.log
)-由于此变量仅适用于该函数,因此它不会更改外部的 same-named 变量。
即使你让它改变了外部变量(通过用 let
而不是 const
声明外部变量并且不隐藏函数内部的变量而是更新它的值),那不会'不能很好地与 React 一起工作。
解决方案是改用状态:
- 将
const themeMode = themes.light
替换为const [themeMode, setThemeMode] = useState(themes.light);
- 在事件处理程序中,将
const themeMode = darkmode ? themes.light : themes.dark;
替换为setThemeMode(darkmode ? themes.light : themes.dark);
进行上述 2 项更改会奏效 - 但您仍然可以大大简化您的组件。您不需要状态中的 darkMode
和 themeMode
,因为一个只是从另一个计算得出的。如果你只使用一个状态变量,你也不需要 useEffect
来根据另一个自动更新一个。但我会让您解决这些问题 - 我希望这至少能帮助您入门!