Items in localStorage are working just fine, adding, deleting and saving works as it should, but if i choose dark theme and reload page, it will be light again, how can i fix it?
class TodoList extends React.Component {
constructor(props) {
super(props);
this.state = {
items: [],
theme: 'theme' ? 'dark' : 'light'
};
this.switchTheme = this.switchTheme.bind(this);
this.addItem = this.addItem.bind(this);
this.deleteItem = this.deleteItem.bind(this);
}
switchTheme() {
const theme = this.state.theme === 'light' ? 'dark' : 'light';
this.setState({ theme });
document.documentElement.setAttribute('data-theme', theme);
}
addItem(e) {
...
}
deleteItem(key) {
...
}
render() {
return (
...
<button className='button-switch' onClick = { this.switchTheme }>Switch theme</button>
);
}
componentWillMount() {
this.setState({
items: JSON.parse(localStorage.getItem('items')),
theme: JSON.parse(localStorage.getItem('theme'))
})
}
componentDidUpdate() {
localStorage.setItem('items', JSON.stringify(this.state.items));
localStorage.setItem('theme', JSON.stringify(this.state.theme));
}
}
export default TodoList;
In your sample code, you are only updating the data-theme
html attribute inside the switchTheme
function:
document.documentElement.setAttribute('data-theme', theme);
So in your example, you also need to set the attribute before the component mounts for the first time, inside your componentWillMount
:
componentWillMount() {
this.setState({
items: JSON.parse(localStorage.getItem('items')),
theme: JSON.parse(localStorage.getItem('theme'))
})
document.documentElement.setAttribute('data-theme', this.state.theme);
}
However, componentWillMount is deprecated and you shouldn't use it if possible.
Here is a codesandbox example that removes the deprecated method and instead sets the theme from local storage inside the constructor.
See the getInitialTheme
function called from the constructor when the component renders:
constructor(props) {
super(props);
this.state = {
items: [],
theme: this.getInitialTheme()
};
this.switchTheme = this.switchTheme.bind(this);
}
// checks if local storage is available, and returns the value from it if so. if not, returns
// a default of 'light'
getInitialTheme() {
try {
const savedTheme = JSON.parse(localStorage.getItem("theme")) || "light";
// make sure we update the data-theme property with the localstorage value when the component
// first renders
document.documentElement.setAttribute("data-theme", savedTheme);
return savedTheme;
} catch {
// local storage is not available, e.g. the user is using incognito
return "light";
}
}