React 18Alpha - Redux 7.2.4 - redux-thunk 2.3.0 - redux-storage 4.1.2
I have the following error in the Redux Store state, it seems that the reducers are duplicating the state for each node:
const rootReducer = combineReducers({
serverSettings,
userSettings,
});
I have tried many different ways to get the state to not duplicate but everything fails, the reducers and the actions are really simple, they take in a userSettings or a serverSettings object that has all the changes done to the object in the view to update the store:
export default function userSettingsReducer(
state: IDefaultState = defaultState,
action: UserSettingsAction
): IDefaultState {
switch (action.type) {
case USER_SETTINGS_SAVE:
return { ...state, userSettings: action.userSettings };
case USER_SETTINGS_LOAD:
return { ...state, userSettings: action.userSettings };
default:
return state;
}
}
the actions are also as simple as it gets:
export const ActionSaveUserSettings =
(userSettings: UserSettings) => (dispatch: Dispatch<UserSettingsAction>) => {
dispatch({ type: USER_SETTINGS_SAVE, userSettings: userSettings });
};
Each time the action is dispatched I pass the whole userSettings object to the store to save with the changes already done to the object to make the reducers and actions as simple as possible:
const handleOrderSizesChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
dispatch(ActionSaveUserSettings({ ...userSettings, OrderSizes: { ...userSettings.OrderSizes, [e.target.name]: e.target.value } }))
}
This is the store file:
import { createStore, combineReducers, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import { composeWithDevTools } from 'redux-devtools-extension';
import { createLogger } from 'redux-logger';
import serverSettings from "./reducers/serverSettingsReducer";
import userSettings from './reducers/userSettingsReducer';
import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux';
import { save, load } from "redux-localstorage-simple"
const rootReducer = combineReducers({
serverSettings,
userSettings,
});
const logger = createLogger();
const enhancer = composeWithDevTools(applyMiddleware(save(), thunk, logger));
export const store = createStore(rootReducer, load(), enhancer);
export type RootState = ReturnType<typeof store.getState>
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector
export type AppDispatch = typeof store.dispatch
export const useAppDispatch = () => useDispatch<AppDispatch>()
export default store;
this is the default state:
export interface IDefaultState {
serverSettings: ServerSettings;
userSettings: UserSettings;
}
Update - This fixed the issue:
export default function userSettingsReducer(
state: UserSettings = defaultState.userSettings,
action: UserSettingsAction
): UserSettings {
switch (action.type) {
case USER_SETTINGS_SAVE:
return { ...state, ...action.userSettings };
case USER_SETTINGS_LOAD:
return { ...state };
default:
return state;
}
}
Both your
userSettingsReducer
and theserverSettingsReducer
has the state shape asIDefaultState
.You need to change the type from
IDefaultState
to the respective type as below