Redux in React App duplicating in store when it should not be

84 Views Asked by At

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:

enter image description here

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;
  }
}
1

There are 1 best solutions below

1
On

Both your userSettingsReducer and the serverSettingsReducer has the state shape as IDefaultState .

You need to change the type from IDefaultState to the respective type as below

export default function userSettingsReducer(
  state: UserSettings = defaultState,
  action: UserSettingsAction
): UserSettings`