Blog>
Snippets

Optimizing State Memory Usage for Undo History

Show a method for limiting the size of the state history to prevent memory overuse, including steps for properly discarding the oldest stored states.
function limitStateHistory(state, maxHistorySize) {
    // Ensures that the past array doesn't exceed the specified maxHistorySize
    while (state.past.length > maxHistorySize) {
        // Remove the oldest state from the beginning of the past array
        state.past.shift();
    }
    // Ensure the future array also doesn't exceed the maxHistorySize
    while (state.future.length > maxHistorySize) {
        // Remove the oldest future state
        state.future.pop();
    }
    return state;
}
This function takes a state object and a maximum history size as arguments. It ensures that both the past and future history arrays within the state object do not exceed the specified maximum size. This is done by removing the oldest states from the beginning of the past array and the end of the future array until their size is within limit.
function undoAction(state) {
    // Handle undo action by moving the most recent past state to present
    // and the current present state to the beginning of the future array
    if (state.past.length > 0) {
        const previous = state.past.pop();
        state.future.unshift(state.present);
        state.present = previous;
    }
    return limitStateHistory(state, 2);
}
This function performs an undo operation on the state. It moves the most recent state from the past array to become the current state, and places the old current state at the beginning of the future array. It then invokes the limitStateHistory function to ensure the history arrays do not exceed the specified maximum size.
function redoAction(state) {
    // Handle redo action by moving the first future state to present
    // and the current present state to the end of the past array
    if (state.future.length > 0) {
        const next = state.future.shift();
        state.past.push(state.present);
        state.present = next;
    }
    return limitStateHistory(state, 2);
}
This function performs a redo operation on the state. It moves the first state from the future array to become the current state, and places the old current state at the end of the past array. It also ensures the state’s history size is within the specified maximum limit by invoking the limitStateHistory function.