reactjs - React Hook 在 gatsby 生产模式下的第一次渲染上无法正常工作

标签 reactjs react-hooks gatsby emotion

我有以下问题:

我有一个 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/

相关文章:

reactjs - Font.loadAsync() 无法解析自定义字体的模块(React Native 和 Expo)

reactjs - 我怎样才能将 react 导出到word文档

javascript - 在 native react 中使用带有地理定位的钩子(Hook)/状态我在哪里出错了?

javascript - React : Changing State in functional component also Change functional component's props value, 及其父类状态

javascript - 将 Gatsby JS 站点部署到 Netlify 时出现 "Error running command: Build script returned non-zero exit code"

javascript - JSX 映射函数内部的错误处理

javascript - React + d3 具有不同数据的多个图表组件

reactjs - 无法更新 react Hook 中 setInterval 内的状态

javascript - 如何根据特定页面有条件地在 Gatsby 中呈现组件?

reactjs - 在 React 和 Gatsby 中通过 className 选择 dom 元素的正确方法