redux-subspace was created for a very similar use case (in fact, we have also been migrating 2 seperate apps from angular 1 to react/redux with shared components between them). It allows you to have a single store and isolate a section of it for your shared components.
The basic concept is that the parent app combine's the component's reducer into it's store and then sub stores are created that return a reduced state tree and namespace dispatched actions.
Note: I have not use angular w/ redux and I have no idea how you integrate the two, so I'm only going to show how you can create the sub-stores and hope it works for you (if you do get it working, I'd love to know so we can expand our supported frameworks in our docs).
import { createStore, combineReducers } from 'redux'
import { subspace, namespaced } from 'redux-subspace'
const component1 = (state = { value: 1 }, action) => {
switch (action.type) {
case 'INCREMENT':
return { ...state, value: state.value + 1 }
default:
return state
}
}
const component2 = (state = { value: 10 }, action) => {
switch (action.type) {
case 'DECREMENT':
return { ...state, value: state.value - 1 }
default:
return state
}
}
const reducer = combineReducers({
component1: namespaced('component1')(component1),
component2: namespaced('component2')(component2)
})
const store = createStore(reducer)
const component1Store = subspace((state) => state.subApp1, 'subApp1')(store)
const component2Store = subspace((state) => state.subApp2, 'subApp2')(store)
console.log('store state:', store.getState()) // { "component1": { "value": 1 }, "component2": { "value": 10 } }
console.log('component1Store state:', component1Store.getState()) // { "value": 1 }
console.log('component2Store state:', component2Store.getState()) // { "value": 10 }
Now dipatching actions into those sub-stores will also only affect their state
component1Store.dispatch({ type: 'INCREMENT'})
console.log('store state:', store.getState()) // { "component1": { "value": 2 }, "component2": { "value": 10 } }
console.log('component1Store state:', component1Store.getState()) // { "value": 2 }
console.log('component2Store state:', component2Store.getState()) // { "value": 10 }
component2Store.dispatch({ type: 'INCREMENT'})
console.log('store state:', store.getState()) // { "component1": { "value": 2 }, "component2": { "value": 10 } }
console.log('component1Store state:', component1Store.getState()) // { "value": 2 }
console.log('component2Store state:', component2Store.getState()) // { "value": 10 }
Notice that the INCREMENT
action dipatched into the component2Store
did not change the state of component1Store
. The situation is reversed if we dispatch a DECREMENT
action
component1Store.dispatch({ type: 'DECREMENT'})
console.log('store state:', store.getState()) // { "component1": { "value": 2 }, "component2": { "value": 10 } }
console.log('component1Store state:', component1Store.getState()) // { "value": 2 }
console.log('component2Store state:', component2Store.getState()) // { "value": 10 }
component2Store.dispatch({ type: 'DECREMENT'})
console.log('store state:', store.getState()) // { "component1": { "value": 2 }, "component2": { "value": 9 } }
console.log('component1Store state:', component1Store.getState()) // { "value": 2 }
console.log('component2Store state:', component2Store.getState()) // { "value": 9 }
At this point, you would need to work out how to inject these sub-stores into your shared components.
Hope this is useful for you.
Disclaimer: I am the author of redux-subspace