这是一个关于将redux与第三方库混合的hacky-ish问题。我很清楚这与Redux指南相反。它主要用于讨论和探索 - 我也不想污染他们的Github问题;)
第三方数据 我们使用关系和不可变数据结构模块来存储我们的应用程序数据。简而言之,该模块有点像关系数据库:
当前的Redux商店结构
由于我们使用Redux,我们最初选择NOT不直接公开表,因为它们包含方法。我们改为公开Table.get();
的结果,它返回一个数组对象的数组。
因此我们的减速器通过使用第三方模块“更新状态”。繁重的工作由第三方完成,减速器基本上总是返回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来处理第三方数据,并在Store结构中公开“Tables”.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({
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();
由于我们使用选择器(重新选择)获取数据,因此我们的情况不会导致问题,并且他们知道数据何时发生了变化,即使它们必须经过{{1 }}
我不安/不确定的是Redux预期或完成的任何其他事情。这样的结构会破坏什么吗?
答案 0 :(得分:3)
这两个选项都与Redux应用程序的工作方式相反,因为您依赖数据突变而不是返回新对象。
虽然从技术上讲你可以使用Redux改变数据我认为在这种情况下它比它的价值更麻烦,因为你并没有真正从Redux中获益。例如,视图无法有效地重绘,因为突变使得无法一眼就看出哪些数据发生了变化。
这就是为什么我建议您不要使用Redux,如果您想将特定的客户端数据库视为事实的来源。如果 it 是真相的来源,Redux只会运作良好。因此,只需直接使用数据库和/或围绕它构建一个更符合您要做的事情的抽象。
答案 1 :(得分:1)
据我了解,Redux并不关心您的商店是什么样的。这是一个抽象。你决定它的外观。您还可以决定操作如何影响Reducer。决定公开方法和/或数据是诚实无关的。只要你坚持你的设计决定,什么都不会打破。我唯一要警惕的是,通过公开方法而不仅仅是数据,你的应用程序状态是否真的是不可变的。
除此之外,知道您的应用程序状态由第三方方法反映意味着您需要开发组件。它可能不是商定的理想例子,但这并不意味着你不能这样做。无论如何,这是我的意见。
答案 2 :(得分:0)
您可能需要查看https://github.com/tommikaikkonen/redux-orm。它提供了一个类似于“模型”的类似于Redux风格的不可变减少器的API。还是新的,但到目前为止似乎非常有用。