I have an issue in redux-toolkit. What I am trying to do is to save the state of a redux as a snapshot file and load this state later with the help of replaceReducer function.
currently my state gets loaded but I have a problem with actions. they don't work anymore after new state is loaded what seems to be the problem?
store.js
import { configureStore, combineReducers } from '@reduxjs/toolkit';
import infoReducer from '../features/renderer/rendererSlice';
import cameraReducer from '../features/camera/cameraSlice';
import modalsreducer from '../features/modal/modalSlice';
import globalsReducer from '../features/global/globalsSlice';
import treeReducer from '../features/tree/treeSlice';
import modelReducer from '../features/model/modelSlice';
import eventReducer from '../features/event/eventSlice';
export const rootReducer = combineReducers({
globals: globalsReducer,
renderer: infoReducer,
camera: cameraReducer,
modal: modalsreducer,
tree: treeReducer,
model: modelReducer,
event: eventReducer,
});
const store = configureStore({
reducer: rootReducer,
middleware: (getDefaultMiddleware) => getDefaultMiddleware({ serializableCheck: false }),
});
export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
export default store;
snapModal.tsx
const handleSaveSnapshot = (): void => {
onClose(false);
const state = store.getState();
console.log(state)
const stateJSON = JSON.stringify(state);
const blob = new Blob([stateJSON], { type: 'application/json' });
const timestamp = new Date().toISOString();
const filename = `${timestamp}-tracer-snapshot.json`;
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = filename;
link.click();
URL.revokeObjectURL(url);
};
const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>): void => {
const file = event.target.files?.[0];
if (file) {
const reader = new FileReader();
reader.onload = (): void => {
const stateJSON = reader.result as string;
const newState = JSON.parse(stateJSON);
store.replaceReducer(() => newState);
};
reader.readAsText(file);
}
event.target.value = '';
};
store.replaceReducer
is most likely the wrong approach for this. It's documented as a way to do code-splitting because it replaces the root reducer whereas you want to load state from a json file into the existing reducers if I understood it correctly.
I'd look into https://redux-toolkit.js.org/api/configureStore#preloadedstate and create a function that can re-initialize the store with preloadedState
. An alternative would be to search for a middleware that offers file-based state loading.