useContext 传递了错误的 props
useContext passing wrong props
我的 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
的数据传递到我的组件中?
因为我的应用程序使用的是每页布局,所以我在我的布局文件中插入了 AppWrapper
而不是 _app.tsx
并且一切正常
import Header from './header'
import Footer from './footer'
import { AppWrapper } from '../contexts/AppContext';
interface LayoutProps {
children: React.ReactNode
}
const Layout = ({ children }: LayoutProps) => {
return (
<AppWrapper>
<Header />
{children}
<Footer />
</AppWrapper>
)
}
export const getLayout = (page: LayoutProps) => <Layout>{page}</Layout>;
export default Layout
我的 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
的数据传递到我的组件中?
因为我的应用程序使用的是每页布局,所以我在我的布局文件中插入了 AppWrapper
而不是 _app.tsx
并且一切正常
import Header from './header'
import Footer from './footer'
import { AppWrapper } from '../contexts/AppContext';
interface LayoutProps {
children: React.ReactNode
}
const Layout = ({ children }: LayoutProps) => {
return (
<AppWrapper>
<Header />
{children}
<Footer />
</AppWrapper>
)
}
export const getLayout = (page: LayoutProps) => <Layout>{page}</Layout>;
export default Layout