I'm trying to access the value of ThemeContext.Consumer
in my styled components. I'm using Gatsby to implement dark mode.
This is the ThemeContext.Consumer
file:
import React from 'react'
const defaultState = {
dark: false,
toggleDark: () => {},
}
const ThemeContext = React.createContext(defaultState)
// Getting dark mode information from OS!
// You need macOS Mojave + Safari Technology Preview Release 68 to test this currently.
const supportsDarkMode = () =>
window.matchMedia('(prefers-color-scheme: dark)').matches === true
class ThemeProvider extends React.Component {
state = {
dark: false,
}
componentDidMount() {
// Getting dark mode value from localStorage!
const lsDark = JSON.parse(localStorage.getItem('dark'))
if (lsDark) {
this.setState({ dark: lsDark })
} else if (supportsDarkMode()) {
this.setState({ dark: true })
}
}
// https://stackoverflow.com/questions/59005886/eslint-prevent-using-this-state-within-a-this-setstate-react-no-access-state-i?stw=2
toggleDark = () => {
const dark = !this.state.dark
localStorage.setItem('dark', JSON.stringify(dark))
this.setState(({ dark }) => ({ dark: !dark }))
}
render() {
const { children } = this.props
const { dark } = this.state
return (
<ThemeContext.Provider
value={{
dark,
toggleDark: this.toggleDark,
}}
>
{children}
</ThemeContext.Provider>
)
}
}
export default ThemeContext
export { ThemeProvider }
This is my Header.js file
:
import React from 'react'
import styled from 'styled-components'
import ThemeContext from '../context/ThemeContext'
class Header extends React.Component {
render() {
const currentTheme = this.props.theme
return (
<ThemeContext.Consumer>
{theme => (
<HeaderWrapper>
<span
role="presentation"
className="dark-switcher"
onClick={theme.toggleDark}
>
{theme.dark ? <span>☀</span> : <span>☾</span>}
</span>
</HeaderWrapper>
)}
</ThemeContext.Consumer>
)
}
}
export default Header
const HeaderWrapper = styled.div`
background: ${() => (theme.dark ? '#C6D0EB' : '#205284')};
border-bottom: 1px solid var(--accents-2);
`
I added const currentTheme = this.props.theme
to be able to use the value globally. With expectation of being able to use it inside my styled component.
Any suggestions on how to approach this problem?