【发布时间】:2016-01-07 13:06:41
【问题描述】:
这是一个关于将 redux 与 3rd 方库混合的问题。我很清楚这与 Redux 指南相反。主要是为了讨论和探索——我也不想污染他们的 Github 问题;)
第三方数据 我们使用关系和不可变数据结构模块来存储我们的应用程序数据。简而言之,该模块的工作方式有点像关系数据库:
- 它公开了表格
- 表格包含应用程序数据
- 表有 4 种方法:get、post、put、delete
- 数据对象通过索引/主键动态地相互引用
当前的 Redux 存储结构
由于我们使用的是 Redux,我们最初选择不直接公开表,因为它们包含方法。我们改为公开Table.get(); 的结果,它返回它的数据对象数组。
因此,我们的 reducer 通过使用 3rd 方模块来“更新状态”。重载由第 3 方完成,减速机基本总是返回Table.get();。
我们的商店看起来像这样:
// the application data (built by relational-json)
var appDB = {
People: {
get: function() {},
post: function() {},
put: function() {},
delete: function() {}
},
Organization: {
get: function() {},
post: function() {},
put: function() {},
delete: function() {}
},
Address: {
get: function() {},
post: function() {},
put: function() {},
delete: function() {}
}
};
// example Reducer
store = createStore(combineReducers({
Person: function personReducer(state, action) {
"use strict";
switch (action.type) {
case "UPDATE_PERSON_LIST":
case "UPDATE_PERSON": {
appDB.Person.put(action.data, "Person");
return appDB.Person.get();
}
case "CREATE_PERSON": {
appDB.Person.post(action.data, "Person");
return appDB.Person.get();
}
default: {
return appDB.Person.get();
}
}
},
Organization: function personReducer(state, action) {
"use strict";
switch (action.type) {
case "UPDATE_ADDRESS_LIST":
case "UPDATE_ADDRESS": {
appDB.Organization.put(action.data, "Organization");
return appDB.Organization.get();
}
case "CREATE_ADDRESS": {
appDB.Organization.post(action.data, "Organization");
return appDB.Organization.get();
}
default: {
return appDB.Organization.get();
}
}
},
Address: function personReducer(state, action) {
"use strict";
switch (action.type) {
case "UPDATE_ADDRESS_LIST":
case "UPDATE_ADDRESS": {
appDB.Address.put(action.data, "Address");
return appDB.Address.get();
}
case "CREATE_ADDRESS": {
appDB.Address.post(action.data, "Address");
return appDB.Address.get();
}
default: {
return appDB.Address.get();
}
}
}
}));
// resulting initial state looks like:
var state = {
Person: [],
Organization: [],
Address: []
};
我们的实际设置如上所示,但有近 100 个减速器。大多数减速器也非常相同。它们唯一的变化通常是操作的类型和要更新的表。
问题
另类商店结构? 我们正在考虑使用单个 reducer 来处理第 3 方数据,并在 Store 结构中公开“Tables”.get()。这样我们的 store 就会有一个更简单的结构(和更少的 reducer),看起来像:
// the application data (built by relational-json)
var appDB = {
People: {
get: function() {},
post: function() {},
put: function() {},
delete: function() {}
},
Organization: {
get: function() {},
post: function() {},
put: function() {},
delete: function() {}
},
Address: {
get: function() {},
post: function() {},
put: function() {},
delete: function() {}
}
};
// example Reducer
store = createStore(combineReducers({
appDB: function dbReducer(state, action) {
"use strict";
switch (action.type) {
case "UPDATE_PERSON_LIST":
case "UPDATE_PERSON": {
appDB.Person.put(action.data, "Person");
break;
}
case "CREATE_PERSON": {
appDB.Person.post(action.data, "Person");
break;
}
case "UPDATE_ORGANIZATION_LIST":
case "UPDATE_ORGANIZATION": {
appDB.Organization.put(action.data, "Organization");
break;
}
case "CREATE_ORGANIZATION": {
appDB.Organization.post(action.data, "Organization");
break;
}
case "UPDATE_ADDRESS_LIST":
case "UPDATE_ADDRESS": {
appDB.Address.put(action.data, "Address");
break;
}
case "CREATE_ADDRESS": {
appDB.Address.post(action.data, "Address");
break;
}
default: {
break;
}
}
return Object.keys(appDB).reduce(function(obj, key) {
obj[key] = appDB[key].get;
return obj;
}, {})
}
}));
// resulting initial state looks like:
var state = {
appDB: {
People: function get() {},
Organization: function get() {},
Address: function get() {}
}
};
冲突之处在于apis.apiX 将是上述方法的对象(get)。数据不直接暴露,必须通过Table.get();暴露出来
这在我们的例子中不会造成问题,因为我们使用选择器 (reselect) 获取数据,并且它们知道数据何时发生变化,即使它们必须经过 Table.get();
我感到不安/不确定的是 Redux 预期或完成的任何其他事情。这样的结构会破坏事物吗?
【问题讨论】:
-
非常有趣。您为此使用什么库?
标签: javascript redux