With redux, when you trigger any action, all reducers are called with that particular action and its upto each reducer to handle that action.
When the reducer does not need to handle an action you need to return the orignal state
That is why a default statement in reducer switch function is required
Now in themeReducer
, you initialse the state to be a theme object, but then CHANGE_THEME
action you update the state to just store the name which breaks its storage pattern
Also as a default you are returning the state.name
property which means that the next time the reducer just has state equal to the current theme's name
The solution is to keep storing the required theme is state as an object and in default case return state
Now while using the theme in settings.js you can use theme.name
reducers/theme.js
const themeReducer = (state = themes[0], action) => {
switch (action.type) {
case "CHANGE_THEME":
document.documentElement.style.setProperty(
"--primary-color",
themes[action.payload].colors.primary
);
document.documentElement.style.setProperty(
"--secondary-color",
themes[action.payload].colors.secondary
);
return themes[action.payload];
default:
document.documentElement.style.setProperty(
"--primary-color",
state.colors.primary
);
document.documentElement.style.setProperty(
"--secondary-color",
state.colors.secondary
);
return state;
}
};
export default themeReducer;
Settings.js
function Settings() {
const counter = useSelector(state => state.counter);
const theme = useSelector(state => state.theme);
return (
<div>
<h2>This is the Settings page</h2>
<span>Counter: {counter}</span>
<br />
<span>Current theme: {theme.name}</span>
<Color />
</div>
);
}
Working demo