Nesting Subspaces

As subspaces behave, for all intents and purposes, the same as a regular Redux store, it is possible to create subspaces from other subspaces. This is useful when you want to compose a sub-application from other sub-applications.

Given the following store set up:

import { createStore, combineReducers } from 'redux'
import { subspace, namespaced } from 'redux-subspace'

const counter = (state = { value: 1 }, action) => {
    switch (action.type) {
        case 'INCREMENT':
            return { ...state, value: state.value + 1 }
        default:
            return state
    }
}

subApp1 = combineReducers({
    childApp: namespaced('childApp')(counter),
    subApp: counter
})

const reducer = combineReducers({
    subApp1: namespaced('subApp1')(subApp1),
    subApp2: namespaced('subApp2')(counter)
})

const store = createStore(reducer)

const subApp1Store = subspace((state) => state.subApp1, 'subApp1')(store)
const subApp2Store = subspace((state) => state.subApp2, 'subApp2')(store)

const childAppStore = subspace((state) => state.childApp, 'childApp')(subApp1Store)

This store's state will now look like:

{
    "subApp1": {
        "childApp": {
            "value": 1
        },
        "subApp": {
            "value": 1
        }
    },
    "subApp2": {
        "value": 1
    }
}

When dispatching actions into childAppStore, only the counter for the childApp will change:

childAppStore.dispatch({ type: 'INCREMENT' })

console.log('childApp state:', childAppStore.getState()) // { "value": 2 }

console.log('subApp1 state:', subApp1Store.getState()) // { "childApp": { "value": 2 }, "subApp": { "value": 1 } }
console.log('subApp2 state:', subApp2Store.getState()) // { "value": 1 }

console.log('store state:', store.getState()) // { "subApp1": { "childApp": { "value": 2 }, "subApp": { "value": 1 } }, subApp2: { value: 1 } }

When dispatching actions into subApp1Store, the child app counter is not affected:

subApp1Store.dispatch({ type: 'INCREMENT' })

console.log('childApp state:', childAppStore.getState()) // { "value": 2 }

console.log('subApp1 state:', subApp1Store.getState()) // { "childApp": { "value": 2 }, "subApp": { "value": 2 } }
console.log('subApp2 state:', subApp2Store.getState()) // { "value": 1 }

console.log('store state:', store.getState()) // { subApp1: { "childApp": { "value": 2 }, "subApp": { "value": 2 } }, subApp2: { value: 1 } }

Likewise, when dispatching actions into subApp2Store or the root Redux store, the child app counter is not affected:

subApp2Store.dispatch({ type: 'INCREMENT' })

console.log('childApp state:', childAppStore.getState()) // { "value": 2 }

console.log('subApp1 state:', subApp1Store.getState()) // { "childApp": { "value": 2 }, "subApp": { "value": 2 } }
console.log('subApp2 state:', subApp2Store.getState()) // { "value": 2 }

console.log('store state:', store.getState()) // { subApp1: { "childApp": { "value": 2 }, "subApp": { "value": 2 } }, subApp2: { value: 2 } }

store.dispatch({ type: 'INCREMENT' })

console.log('childApp state:', childAppStore.getState()) // { "value": 2 }

console.log('subApp1 state:', subApp1Store.getState()) // { "childApp": { "value": 2 }, "subApp": { "value": 2 } }
console.log('subApp2 state:', subApp2Store.getState()) // { "value": 2 }

console.log('store state:', store.getState()) // { subApp1: { "childApp": { "value": 2 }, "subApp": { "value": 2 } }, subApp2: { value: 2 } }

Subspaces can be nested arbitrarily deep, so you can slice your application into sub-applications in whatever way make the most sense to you.

results matching ""

    No results matching ""