【发布时间】:2020-08-28 16:53:55
【问题描述】:
我有以下问题:
我有一个gatsby 网站,它使用emotion 用于js 中的css。我使用emotion theming 来实现暗模式。当我运行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,加载 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>
)
}
但这会导致页面加载时出现难看的闪烁。
第一种方法中的钩子我做错了什么,初始值没有按我的预期工作。
【问题讨论】:
-
如何呈现布局提供程序。你是使用wrapRootElement还是直接在每个页面中添加?
-
@ShubhamKhatri 我使用
gatsby-plugin-layout将所有页面包装到布局提供程序中。 -
isReady似乎毫无意义——你能通过改变 orf 1st 和 3rd useEffect 的顺序来做同样的事情吗?并且控制台日志可能会导致闪烁。最好的方法是预取并传入 isDark 的值。
标签: reactjs react-hooks gatsby emotion