Redux store 应该是一个用于每个模块或一个用于由多个 mudule 组成的整个应用程序
Posted
技术标签:
【中文标题】Redux store 应该是一个用于每个模块或一个用于由多个 mudule 组成的整个应用程序【英文标题】:Redux store should be one for each module or one for whole application comprising of a multiple mudules 【发布时间】:2018-03-02 18:36:49 【问题描述】:我正在使用 Redux 集成或重写我的 Angular 1 应用程序。它具有以下架构:
app1 => App1 running on diff subdomain
app2 => App2 running on diff subdomain
and so on...
shared => Shared modules(with multiple components) b/w app1 and app2
一个应用由多个模块组成。 共享目录包含一个或多个模块,在两个或多个应用程序之间共享
所以我的问题是我应该有应用级商店还是模块级商店。
我的意思是应用级商店和模块级商店,例如:
-
假设我们有一个共享模块
SM1
在两个应用程序之间共享。
SM1
在app1
内部使用时应使用app1
的存储,在app2
内部使用时应使用app2
的存储。但是一个模块应该是一个自我维持的实体,它不应该依赖任何其他东西来存储它。
或者SM1
可以有自己的商店,不与任何应用程序共享。但是当SM1
在app1
里面使用时,它的store会和app1
的store冲突。
此外,如果我使用模块级存储,则模块和应用程序都需要提供 ngRedux
依赖项,这似乎有点多余。
就可扩展架构和redux
核心原则而言,这里的最佳解决方案是什么?
【问题讨论】:
【参考方案1】:我会尽可能地采用松散耦合:
app1 - 自有商店(集成 sm 商店) app2 - 自有商店(集成 sm 商店) sm - 自己的商店【讨论】:
【参考方案2】:redux-subspace 是为一个非常相似的用例创建的(事实上,我们也一直在将 2 个单独的应用程序从 angular 1 迁移到 react/redux 以及它们之间的共享组件)。它允许您拥有一个单独的商店并为您的共享组件隔离其中的一部分。
基本概念是父应用程序将组件的 reducer 组合到它的 store 中,然后创建子 store 以返回简化的状态树和命名空间调度的操作。
注意:我没有使用 angular w/redux,我不知道你如何整合这两者,所以我只会展示如何创建子商店并希望它对你有用(如果你这样做让它工作,我很想知道,这样我们就可以在我们的文档中扩展我们支持的框架)。
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
现在将操作分配到这些子商店也只会影响它们的状态
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
请注意,INCREMENT
操作转移到 component2Store
并没有更改 component1Store
的状态。如果我们发送一个DECREMENT
操作,情况就相反了
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
此时,您需要弄清楚如何将这些子存储注入到您的共享组件中。
希望这对你有用。
免责声明:我是redux-subspace的作者
【讨论】:
但是如果我将我的商店映射到稍微精确地复制我的后端数据库,那么商店中的项目不应该有任何冲突。在这种情况下,为什么要使用 redux-subspace? 它可能适合您,也可能不适合您(如果不适合,也没有难过的感觉)。 redux-subspace 的主要优点是你的SM1
store 有一个已知的状态起点,所以app1
和app2
可以将SM1
reducer 组合到他们想要的任何地方(例如不同级别的嵌套,不同的键等)。另一个优点是来自SM1
的操作获取命名空间,因此它们不会与使用具有相同操作类型的操作的其他子模块发生任何串扰。随着每个应用程序的发展以及添加越来越多的子模块(甚至子子模块),这种隔离使未来的维护变得更加容易。以上是关于Redux store 应该是一个用于每个模块或一个用于由多个 mudule 组成的整个应用程序的主要内容,如果未能解决你的问题,请参考以下文章
React-Redux:是不是应该将所有组件状态保存在 Redux Store 中