我有以下问题:
我有一个 gatsby
网站,它在 js 中使用 emotion
的 CSS。我使用情感主题
来实现深色模式。当我运行 gatsbydevelop
时,深色模式可以按预期工作,但如果我使用 gatsbybuild&&gatsbyserve
运行它,深色模式就不起作用。更具体地说,深色模式仅在切换到浅色并再次返回后才起作用。
我必须遵循处理主题的顶级组件:
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
加载 darkMode 将按预期工作,但 lightMode 已损坏。我让它工作的唯一方法是使用以下代码按时加载后自动重新渲染。
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>
)
}
但这会导致页面加载时出现难看的闪烁。
我在第一种方法中对钩子(Hook)做错了什么,初始值没有按我的预期工作。
最佳答案
您是否尝试过这样设置初始状态?
const [isDark, setIsDark] = useState(getInitialIsDark())
请注意,我没有将 getInitialIsDark() 包装在附加函数中:
useState(() => getInitialIsDark())
您的构建可能会崩溃,因为在构建时未定义 localStorage
。您可能需要检查 getInitialIsDark
中是否存在该内容。
希望这有帮助!
关于reactjs - React Hook 在 gatsby 生产模式下的第一次渲染上无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61758672/