Reputation: 1137
I'm starting to work with the context api in React, and I decided to make a simple theme context. For now, if I go to my React DevTools and change the boolean isLightTheme to false, it works, but when i try to attach this functionality to a button, i keep getting errors. Can saomeone help me with that?
theme context
import React, { useState, createContext } from 'react'
export const ThemeContext = createContext()
export const ThemeContextProvider = ({ children }) => {
const [state, setState] = useState({
isLightTheme: true,
light: { syntax: '#555', ui: '#ddd', bg: '#eee' },
dark: { syntax: '#ddd', ui: '#333', bg: '#555' }
})
const toggleTheme = () => {
setState({ isLightTheme: !state.isLightTheme})
}
return (
<ThemeContext.Provider value={{...state, toggleTheme}}>
{children}
</ThemeContext.Provider>
)
}
import React, { useContext } from 'react'
import { ThemeContext } from '../context/ThemeContext'
export const ThemeToggler = () => {
const themeContext = useContext(ThemeContext)
const { toggleTheme } = themeContext
return (
<button onClick={toggleTheme}>Change Theme</button>
)
}
Upvotes: 1
Views: 118
Reputation: 3774
The useState
hooks API doesn't update a selective piece of state like setState
does. It'll override the entire state. Here when you toggle the theme, the new state is only
{ isLightTheme: !state.isLightTheme}
with no light and dark keys. You just need to handle this by only updating that piece of state. This should work :
import React, { useState, createContext } from 'react'
export const ThemeContext = createContext()
export const ThemeContextProvider = ({ children }) => {
const [state, setState] = useState({
isLightTheme: true,
light: { syntax: '#555', ui: '#ddd', bg: '#eee' },
dark: { syntax: '#ddd', ui: '#333', bg: '#555' }
})
const toggleTheme = () => {
//preserve the remaining state also
setState({...state,isLightTheme: !state.isLightTheme})
}
return (
<ThemeContext.Provider value={{...state, toggleTheme}}>
{children}
</ThemeContext.Provider>
)
}
Hope this helps !
Upvotes: 1