Leon
Leon

Reputation: 124

Overwriting state tree in react redux

Hey guys so I have a unique use case where I want to override the entire app state tree in redux from one of the reducers from combineReducer. Purpose being I want to be able to load a different session of the app (kinda like a save button).

However I don't know how to go about this, I can easily get the entire state from getState and store it but there doesn't seem to be one to set it. I've also tried looking into redux-persist but I'm not too sure how to pass the persister object to different component.

Any hints or clue? Thanks

Upvotes: 3

Views: 4590

Answers (2)

Vasi
Vasi

Reputation: 1227

You can use Higher Order Reducer to replace whole the app's state.

Higher Order Reducer

Refer this link.

If you have any doubt on this ask that in comments.

const {combineReducers, createStore} = require('redux');

function todos(state=[], action){
    switch (action.type) {
        case 'ADD_TODO':
            return [...state, action.data];
        default:
            return state;
    }
}

var state = {
    todos: ['todo1']
}

var reducers = combineReducers({
    todos: todos
});

var store = createStore(HigherOrderReducer(reducers), state);

function HigherOrderReducer(reducers, initialState){
    let higherState = {
        state: initialState
    }
    return function(state = {}, action){
        switch (action.type) {
            case 'REPLACE_WHOLE_STATE':
                higherState.state = action.data;
                return higherState.state;
            default:
                return reducers(state, action);
        }
    }
}

store.subscribe(function(){
    console.log(store.getState());
})

store.dispatch({
    type: 'ADD_TODO',
    data: 'todo2'
})

var newState = {
    todos: ['task1', 'task2']
}

store.dispatch({
    type: 'REPLACE_WHOLE_STATE',
    data: newState
})

Upvotes: 7

Louis
Louis

Reputation: 1241

You should be able to replace the entire state in the reducer itself. So, instead of doing something like object.assign({}, state, {...}) you would just return newState.

If what you are trying to do is to completely replace the state from the root-reducer level, you can write a conditional based on the combined states.

combineReducer(AReducer, BReducer, (CReducer.someCondition? CReducer : DReducer))

It's all just javascript. An alternative to all this is to use reduce-reducers to merge and generate a new state at whichever level you choose (root reducer or reducer).

Upvotes: 1

Related Questions