【发布时间】:2021-12-29 08:37:16
【问题描述】:
我的AppContext.tsx 文件中有我的上下文提供程序
import { useState, useEffect, useContext, createContext } from 'react';
interface AppContextProps {
children: React.ReactNode
}
const themes = {
dark: {
backgroundColor: 'black',
color: 'white'
},
light: {
backgroundColor: 'white',
color: 'black'
}
}
const initialState = {
dark: false,
theme: themes.light,
toggle: () => { console.log('toggle from initalState') }
}
const AppContext = createContext(initialState);
export function AppWrapper({ children }: AppContextProps) {
const [dark, setDark] = useState(false) // Default theme is light
// On mount, read the preferred theme from the persistence
useEffect(() => {
const isDark = localStorage.getItem('dark') === 'true'
setDark(isDark)
}, [dark])
// To toggle between dark and light modes
const toggle = () => {
console.log('toggle from AppWrapper')
const isDark = !dark
localStorage.setItem('dark', JSON.stringify(isDark))
setDark(isDark)
}
const theme = dark ? themes.dark : themes.light
return (
<AppContext.Provider value={{ theme, dark, toggle }}>
{children}
</AppContext.Provider>
);
}
export function useAppContext() {
return useContext(AppContext);
}
我将Appwrapper 插入到我的_app.tsx 文件中
import type { ReactElement, ReactNode } from 'react'
import type { NextPage } from 'next'
import type { AppProps } from 'next/app'
import { AppWrapper } from '../contexts/AppContext';
import 'normalize.css/normalize.css';
import '../styles/globals.scss'
type NextPageWithLayout = NextPage & {
getLayout?: (page: ReactElement) => ReactNode
}
type AppPropsWithLayout = AppProps & {
Component: NextPageWithLayout
}
const App = ({ Component, pageProps }: AppPropsWithLayout) => {
const getLayout = Component.getLayout ?? ((page) => page)
return getLayout(
<AppWrapper>
<Component {...pageProps} />
</AppWrapper>
)
}
export default App
然后我调用并导入 useAppContext 钩子以在我的 Header 组件中使用它
import styles from './header.module.scss'
import { useAppContext } from '../contexts/AppContext'
const Header = () => {
const { theme, toggle, dark } = useAppContext()
return (
<header className={styles.header}>
<nav className={styles.nav}>
<div onClick={toggle} className={styles.switchWrap}>
<label className={styles.switch}>
<input type="checkbox" />
<span className={styles.slider}></span>
</label>
</div>
</nav>
</header>
)
}
export default Header
但是,我的 toggle 函数记录 toggle from initalState 而不是 toggle from AppWrapper。
以下代码
const { theme, toggle, dark } = useAppContext()
从initialState获取数据
const initialState = {
dark: false,
theme: themes.light,
toggle: () => { console.log('toggle from initalState') }
}
而不是我传递给下面显示的value 道具
<AppContext.Provider value={{ theme, dark, toggle }}>
{children}
</AppContext.Provider>
如何正确地将 value 道具数据而不是来自 initialState 的数据传递到我的组件中?
【问题讨论】:
标签: reactjs react-hooks next.js react-context