gpt4 book ai didi

javascript - 当响应上下文变量更改时页面不会重新渲染

转载 作者:行者123 更新时间:2023-12-02 22:10:18 25 4
gpt4 key购买 nike

我正在使用 React 上下文来保持全局主题状态。

import React, { useState, createContext } from "react"

const ThemeContext = createContext(localStorage.getItem("theme") || "light")

export const ThemeStore = ({ children }) => {
const [theme, setTheme] = useState(localStorage.getItem("theme") || "light")

const handleThemeChange = theme => {
setTheme(theme)
localStorage.setItem("theme", theme === "dark" ? "dark" : "light")
}

return (
<ThemeContext.Provider value={{ theme, changeTheme: handleThemeChange }}>
{children}
</ThemeContext.Provider>
)
}

export default ThemeContext

我在布局组件中提供此上下文,以便我的整个应用程序可以访问商店。下面是我的布局组件。

import React, { useContext } from "react"
import PropTypes from "prop-types"

import Header from "./header"
import "../styles/layout.css"
import ThemeContext, { ThemeStore } from "../contexts/ThemeContext"
import MobileBottomNav from "../components/mobileBottomNav"

// Wrapper for background color
const Wrapper = ({ children }) => {
const theme = useContext(ThemeContext)

return (
<div className={`${theme.theme === "dark" ? "theme-dark" : "theme-light"}`}>
{children}
</div>
)
}

const Layout = ({ children, hideHeader, hideFooterNavBar }) => {
return (
<ThemeStore>
<Wrapper>
<div className="bg-bg-primary">
<Header hideHeader={hideHeader} />
<main>{children}</main>
<MobileBottomNav hideFooterNavBar={hideFooterNavBar} />
</div>
</Wrapper>
</ThemeStore>
)
}

Layout.propTypes = {
children: PropTypes.node.isRequired,
}

export default Layout

我的标题组件中有一个按钮,可以将主题从浅色更改为深色,反之亦然。我的菜单组件等都改变了它们的颜色,因为我添加了条件类名。

但是在我的登录页面中,该页面也包含在提供程序周围,当状态更改时不会更新。因此,如果我将主题从深色更改为浅色,但它不会重新渲染注册页面,因此颜色不会改变。为什么会这样呢?当主题更改时如何使页面重新渲染以便应用新颜色。

这是我的登录页面。

import React, { useContext } from "react"

import SEO from "../components/seo"
import Layout from "../components/layout"
import ThemeContext from "../contexts/ThemeContext"

const SignInPage = () => {
const theme = useContext(ThemeContext)

// This just logs the initial value of theme, but when I change
// the theme from the header component, this value doesn't log again.
// The component doesn't re-render.
console.log(theme)

return (
<Layout hideFooterNavBar={true}>
<SEO title="Sign In" />
<div>
<div
style={{
paddingTop: "150px",
}}
className="container mx-auto"
>
<p
className={`${
theme.theme === "dark" ? "theme-dark" : "theme-light"
} text-text-primary mb-10`}
>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. In non
sapien blandit, aliquet lorem quis, consectetur tellus. Maecenas ac
nibh eu enim auctor volutpat. Mauris a lacus magna. Proin
sollicitudin mauris sit amet auctor feugiat. Nulla facilisi.
Pellentesque eget massa nec massa porta tristique in vitae ante.
Donec rutrum imperdiet urna.
</p>
</div>
</div>
</Layout>
)
}

export default SignInPage

最佳答案

您的问题是,您在向 ThemeContext.Provider 提供值的地方消耗了 ThemeContext

如果你检查 React 开发工具,你应该会看到你的树看起来像这样:

  • 登录页面
    • 布局
      • 主题商店
      • ThemeContext.Provider
        • 包装

您可以做的是使用 Layout 子组件中的上下文,或者使用更高阶的组件将 ThemeContext 注入(inject) SignInPage 中:

const SignInPage = ({ theme }) => {
// ...
}

export default props => (
<ThemeContext.Consumer>
{theme =>
<SignInPage theme={theme} {...props} />
}
</ThemeContext.Consumer>
)

关于javascript - 当响应上下文变量更改时页面不会重新渲染,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59581677/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com