我有以下问题:
我有一个使用emotion
进行css in js的gatsby
网站。我使用emotion主题
实现了深色模式。当我运行gatsby develop
时,深色模式按预期工作,但是如果我使用gatsby build && gatsby serve
运行它,则无法正常工作。具体来说,在切换到浅色和再次切换到深色之后,深色模式才能正常工作。
我有一个顶级组件来处理主题:
const Layout = ({ children }) => {
const [isDark, setIsDark] = useState(() => getInitialIsDark())
useEffect(() => {
if (typeof window !== "undefined") {
console.log("save is dark " + isDark)
window.localStorage.setItem("theming:isDark", isDark.toString())
}
}, [isDark])
return (
<ThemeProvider theme={isDark ? themeDark : themeLight}>
<ThemedLayout setIsDark={() => setIsDark(!isDark)} isDark={isDark}>{children}</ThemedLayout>
</ThemeProvider>
)
}
getInitalIsDark
函数检查 localStorage 值、操作系统的颜色方案,并默认为 false。如果我运行应用程序并激活深色模式,则会设置 localStorage 值。如果不重新加载应用程序,则 getInitialIsDark
方法返回 true,但 UI 仍呈现浅色主题。在浅色和深色之间切换可以正常工作,只有初始加载无法正常工作。
如果我将 getInitialIsDark
更改为 true
,则深色模式会按预期工作,但浅色模式会出现问题。唯一让此方法正常工作的方式是使用以下代码在加载后自动重新渲染一次。
const Layout = ({ children }) => {
const [isDark, setIsDark] = useState(false)
const [isReady, setIsReady] = useState(false)
useEffect(() => {
if (typeof window !== "undefined" && isReady) {
console.log("save is dark " + isDark)
window.localStorage.setItem("theming:isDark", isDark.toString())
}
}, [isDark, isReady])
useEffect(() => setIsReady(true), [])
useEffect(() => {
const useDark = getInitialIsDark()
console.log("init is dark " + useDark)
setIsDark(useDark)
}, [])
return (
<ThemeProvider theme={isDark ? themeDark : themeLight}>
{isReady ? (<ThemedLayout setIsDark={() => setIsDark(!isDark)} isDark={isDark}>{children}</ThemedLayout>) : <div/>}
</ThemeProvider>
)
}
但是这会导致页面加载时出现不美观的闪烁。
在第一种方法中,我的钩子函数有什么问题,导致初始值没有按照我的期望工作?
gatsby-plugin-layout
将所有页面包装到布局提供程序中。 - quadroid