繁体   English   中英

如何在反应组件内的Javascript中将ThemeContext状态作为变量获取?

[英]How to get ThemeContext state as variable in Javascript inside react component?

我正在使用 Gatsby 制作一个简单的 ReactJS 应用程序,该应用程序使用useContext hook 和ThemeContext向应用程序添加一个深色主题选项。 现在,我有另一个组件使用 react-helmet 将外部 JS 文件添加到页面。 这些文件中有一些代码我想连接到主题状态。

我可以访问“index.js”页面上的主题状态:

const { dark } = useContext(ThemeContext)

我想在外部文件“myscript.js”中编写一些代码,例如

let isDark = dark
if(isDark){
   console.log("Dark theme")
}
else{
   console.log("Light theme")
}

'dark' 来自主题。

您可以在 window 对象上设置一个全局数据属性,您可以在项目中的任何位置使用该属性。 您可以在窗口上将其命名为任何名称。 在这种情况下,我使用__globalData__来防止名称冲突

window.__globalData__ = {
  theme: 'light'
}

在上下文的 Provider 组件中,使用useEffect来侦听主题中的更改并在必要时更新全局值。

import React, { useState, useEffect } from 'react'
import ThemeContext from './ThemeContext' // Assuming this is the path

const ThemeProvider = ({ children }) => {
  const [ theme, setTheme ] = useState('light')
  
  useEffect(() => {
    window.__globalData__ = window.__globalData__ || {} // Make sure global data is defined.
    window.__globalData__.theme = theme
  }, [theme])

  return(
    <ThemeContext.Provider values={[ theme, setTheme ]}>
      {children}
    </ThemeContext.Provider>
  )
}

export default ThemeProvider

然后使用函数检查全局属性的值。

/**
 * Check if dark theme is set when globalData is set on window object.
 * Or return false when globalData is not set, meaning theme is light.
 */
const isDark = () => 
  window.__globalData__ && window.__globalData__.theme ? 
    window.__globalData__.theme === 'dark' :
    false

if (isDark()) {
  console.log("Dark theme")
}
else{
  console.log("Light theme")
}

或者,您可以在主题更改时使用事件来执行某些操作。

为了留在钩子的世界中,您可以创建自己的钩子,该钩子以当前主题作为detail属性调度CustomEvent

const useThemeEvents = () => {
  const dispatch = theme => {
    const event = new CustomEvent('themechange', {
      detail: { theme }
    })
    window.dispatchEvent(event)
  }
  return { dispatch }
}

export { useThemeEvents }

然后在您的提供程序组件中使用钩子。

import React, { useState, useEffect } from 'react'
import ThemeContext from './ThemeContext' // Assuming this is the path
import { useThemeEvents } from './hooks' // Also assuming this is the path

const ThemeProvider = ({ children }) => {
  const [ theme, setTheme ] = useState('light')
  const { dispatch } = useThemeEvents()
  
  useEffect(() => {
    dispatch(theme)
  }, [theme])

  return(
    <ThemeContext.Provider values={[ theme, setTheme ]}>
      {children}
    </ThemeContext.Provider>
  )
}

export default ThemeProvider

现在在您添加的 JS 文件中监听 window 对象上的themechange事件。

window.addEventListener('themechange', ({ detail }) => {
  const { theme } = detail
  if (theme === 'dark') {
    console.log("Dark theme")
  } else {
    console.log("Light theme")
  }
})

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM