React useContext返回默认值



我正试图创建一个基于https://github.com/luisgserrano/react-dark-mode.

这就是创建上下文的地方。

import React from 'react'
const ThemeContext = React.createContext({
theme: '',
toggle: () => {}
})
export default ThemeContext

这是我的useDarkMode挂钩,用于获取/设置localStorage主题。

import { useState, useEffect } from 'react'
const useDarkMode = () => {
const [theme, setTheme] = useState('light')
const setMode = (mode) => {
window.localStorage.setItem('theme', mode)
setTheme(mode)
}
const toggle = () => (theme === 'light' ? setMode('dark') : setMode('light'))
useEffect(() => {
const localTheme = window.localStorage.getItem('theme')
localTheme && setTheme(localTheme)
}, [])
return [theme, toggle]
}
export default useDarkMode

这是我图书馆的索引(反应晚安(。

import React, { useContext } from 'react'
import { ThemeProvider } from 'styled-components'
import { GlobalStyles } from './globalStyles'
import { lightTheme, darkTheme } from './settings'
import ThemeContext from './themeContext'
import useDarkMode from './useDarkMode'
const Provider = ({ children }) => {
const [theme, toggle] = useDarkMode()
return (
<ThemeProvider theme={theme === 'light' ? lightTheme : darkTheme}>
<GlobalStyles />
<ThemeContext.Provider value={{ theme, toggle }}>
<button onClick={toggle}>Toggle</button>
{children}
</ThemeContext.Provider>
</ThemeProvider>
)
}
export const useDarkModeContext = () => useContext(ThemeContext)
export default Provider

最后,这是我尝试使用的示例应用程序。

import React from 'react'
import Provider, { useDarkModeContext } from 'react-goodnight'
const App = () => {
const { theme, toggle } = useDarkModeContext();
console.log(theme)
return (
<Provider>
<div>hey</div>
<button onClick={toggle}>Toggle</button>
</Provider>
)
}
export default App

";切换";库索引中的按钮工作正常,但我的示例应用程序中的按钮不工作。useDarkModeContext((返回空。

可能是什么问题?

谢谢!

你做了错误的

第一个选项

你可以将react-goodnight提供者与你的index.js一起使用,并使用useDarkModeContext(),不要将你的index.js命名为Provider,否则你不能使用来自react-goodnightProvider

import Provider, { useDarkModeContext } from 'react-goodnight'
const Provider = ({ children }) => {
const [theme, toggle] = useDarkMode()
return (
<ThemeProvider theme={theme === 'light' ? lightTheme : darkTheme}>
<GlobalStyles />
<Provider>
<ThemeContext.Provider value={{ theme, toggle }}>
<button onClick={toggle}>Toggle</button>
{children}
</ThemeContext.Provider>
</Provider>  
</ThemeProvider>
)
}

第二选项

您正在index.js中传递ThemeContext,因此您也可以在app.js中访问它

import React, { useContext } from 'react'
import ThemeContext from './themeContext'

const App = () => {
const theme = useContext(ThemeContext);
console.log(theme)
return (
<Provider>
<div>hey</div>
<button onClick={toggle}>Toggle</button>
</Provider>
)
}
export default App

它不起作用的原因是您在打印Provider的同一位置调用useContext

为什么这是错误的?因为useContext查找上下文提供程序。通过将Provider呈现在您调用useContext的同一位置,就没有可查找的父级。示例中的useContext实际上是App组件的一部分,而不是提供者的子级

您所要做的就是将按钮移动到该打印之外的其自己的组件,并且只有在那里才能执行useContext(或者在您的情况下,使用名为useDarkModeContext的方法。

唯一的变化是:

import React from 'react'
import Provider, { useDarkModeContext } from 'react-goodnight'
const App = () => {
return (
<Provider>
<div>hey</div>
<ToggleThemeButton />
</Provider>
)
}
export default App
const ToggleThemeButton = () => {
const { theme, toggle } = useDarkModeContext();
return (
<button onClick={toggle}>Switch Theme outside</button>
);
};

最新更新