[英]How to get ThemeContext state as variable in Javascript inside react component?
I'm using Gatsby to make a simple ReactJS app that uses useContext hook and ThemeContext to add an option of dark theme to the app.我正在使用 Gatsby 制作一个简单的 ReactJS 应用程序,该应用程序使用useContext hook 和ThemeContext向应用程序添加一个深色主题选项。 Now, I have another component that uses react-helmet to add external JS files to the page.
现在,我有另一个组件使用 react-helmet 将外部 JS 文件添加到页面。 There is some code in these files that I want to connect to the theme state.
这些文件中有一些代码我想连接到主题状态。
I am able to access the theme state on the 'index.js' page as :我可以访问“index.js”页面上的主题状态:
const { dark } = useContext(ThemeContext)
I want to write some code in the external file 'myscript.js' like我想在外部文件“myscript.js”中编写一些代码,例如
let isDark = dark
if(isDark){
console.log("Dark theme")
}
else{
console.log("Light theme")
}
where 'dark' is from the theme. 'dark' 来自主题。
You could set a global data property on the window object that you can use anywhere in your project.您可以在 window 对象上设置一个全局数据属性,您可以在项目中的任何位置使用该属性。 You can name this anything on the window.
您可以在窗口上将其命名为任何名称。 In this case I've use
__globalData__
to prevent name collision .在这种情况下,我使用
__globalData__
来防止名称冲突。
window.__globalData__ = {
theme: 'light'
}
From within the Provider component of the context use useEffect
to listen for changes in the theme and update the global value if necessary.在上下文的 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
Then use a function to check the value of the global property.然后使用函数检查全局属性的值。
/**
* 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")
}
Alternatively you could use events to do something whenever the theme changes.或者,您可以在主题更改时使用事件来执行某些操作。
To stay in the world of hooks, you could create your own hook that dispatches a CustomEvent
with the current theme as detail
property.为了留在钩子的世界中,您可以创建自己的钩子,该钩子以当前主题作为
detail
属性调度CustomEvent
。
const useThemeEvents = () => {
const dispatch = theme => {
const event = new CustomEvent('themechange', {
detail: { theme }
})
window.dispatchEvent(event)
}
return { dispatch }
}
export { useThemeEvents }
And then use the hook in your provider component.然后在您的提供程序组件中使用钩子。
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
Now in your added JS file listen for the themechange
event on the window object.现在在您添加的 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.