Javascript 将减压器的内容物拆包到组合减压器中
我正在尝试创建一个小应用程序,并找出在其中组织减缩器的最佳方法。我想从应用程序状态加载JSON,并希望它如下所示:Javascript 将减压器的内容物拆包到组合减压器中,javascript,reactjs,redux,react-redux,Javascript,Reactjs,Redux,React Redux,我正在尝试创建一个小应用程序,并找出在其中组织减缩器的最佳方法。我想从应用程序状态加载JSON,并希望它如下所示: const state = { apple: { quantity: 1, category: "fruit", }, banana: { quantity: 2, category: "fruit", }, avocado: {
const state = {
apple: {
quantity: 1,
category: "fruit",
},
banana: {
quantity: 2,
category: "fruit",
},
avocado: {
quantity: 1,
category: "fruit",
},
onion: {
quantity: 1,
category: "vegetable",
},
beetroot: {
quantity: 2,
category: "vegetable",
},
celeriac: {
quantity: 3,
category: "vegetable",
},
milk: {
quantity: 1,
units: "bottle",
category: "other",
},
sugar: {
quantity: 1,
units: "kg",
category: "other",
},
flour: {
quantity: 1,
units: "kg",
category: "other",
}
};
{
“水果”:[
{“苹果”:1},
{“香蕉”:2},
{“鳄梨”:1}
],
“流浪者”:[
{“洋葱”:1},
{“甜菜根”:2},
{“芹菜”:3}
],
“牛奶”:“1瓶”,
“糖”:“1公斤”,
“面粉”:“1公斤”
}
该应用程序有两个减缩器,用于返回水果和蔬菜的列表,但还有第三个减缩器用于返回包含所有其他字段(如milk、sugar等)的对象。我想了解,是否有可能以某种方式将此reducer的内容解压缩到根reducer中:
//fruitReducer.js
常量initialState={}
导出常量=(状态=初始状态,操作)=>{
开关(动作类型){
加上水果:
返回{…状态,[action.payload.name]:action.payload.value}
}
}
//vagetablesReducer.js
常量initialState={}
导出常量vagetablesReducer=(状态=初始状态,操作)=>{
开关(动作类型){
案例附加值:
返回{…状态,[action.payload.name]:action.payload.value}
}
}
//otherGoodsReducer.js
常量initialState={}
导出常量otherGoodsReducer=(状态=初始状态,操作)=>{
开关(动作类型){
案例添加\其他\良好:
返回{…状态,[action.payload.name]:action.payload.value}
}
}
//rootReducer.js
rootReducer=combinereducer({
迷走神经:迷走神经减压器,
水果:水果减量剂,
//需要在这里打开其他产品的包装吗
})
我还想弄清楚在这种情况下什么是好的做法。我只是对牛奶、糖等有很多相同的输入,用一个还原剂处理它们对我来说很方便。但是现在我不知道如何形成一个适合我的JSON(如果为这些对象创建一个单独的键,这对我不起作用。)。我不喜欢这种结构,但下面是你应该如何做的。您不能使用
combinereducer
,因此需要编写自己的函数来组合它们。它看起来像:
const rootReducer = (state = {}, action) => {
const {vagetables, fruits, ...otherGoods} = state;
return {
vagetables: vagetablesReducer(vagetables, action),
fruits: fruitsReducer(fruits, action),
...otherGoodsReducer(otherGoods, action)
}
}
但这确实是不必要的。如果将所有其他成分存储在名为otherGoods
的属性中,则可以使用combinereducer
rootReducer = combineReducers({
vagetables: vagetableReducer,
fruits: fruitReducer,
otherGoods: otherGoodsReducer
})
当你想以你的应用程序所期望的格式获取配料时,你可以使用选择器
const formatState = (state) => {
const {vagetables, fruits, otherGoods} = state;
return {
vagetables,
fruits,
...otherGoods
}
};
这将返回您期望的JSON。..
其他商品之前的..
排列运算符将其他商品
的每个元素置于返回对象的根
编辑:
在我看来,这个数据集的最佳结构只有一个缩减器,特别是因为您提到要减少代码重复。您应该能够采取“添加配料”、“增加配料”、“设置配料”等一般措施,这些措施同样适用于所有配料,无论是水果、蔬菜还是其他配料
我推荐这样一种状态:
const state = {
apple: {
quantity: 1,
category: "fruit",
},
banana: {
quantity: 2,
category: "fruit",
},
avocado: {
quantity: 1,
category: "fruit",
},
onion: {
quantity: 1,
category: "vegetable",
},
beetroot: {
quantity: 2,
category: "vegetable",
},
celeriac: {
quantity: 3,
category: "vegetable",
},
milk: {
quantity: 1,
units: "bottle",
category: "other",
},
sugar: {
quantity: 1,
units: "kg",
category: "other",
},
flour: {
quantity: 1,
units: "kg",
category: "other",
}
};
数量
始终是一个数字
,因此很容易进行加法和减法等数学运算
units
是一个可选字符串,您可以将其与数量组合以获得类似“1 kg”的字符串
类别
是“水果”、“蔬菜”或“其他”中的一种。您可以使用此字段筛选或分组您的配料
您可以选择将名称
作为每个成分的属性,即使它与键
相同。我喜欢这样做,因为这样你只需要使用Object.values
,你就会得到一个包含名称的完整对象。这使得过滤、排序等变得非常容易
您还可以为每个成分输入唯一的数值
id
,而不是name
,在这种情况下,您可以将name
作为属性。您的状态不需要与要呈现的JSON形状相同。您可以使用选择器重新格式化它。它可能有一个更平坦的结构,其中水果和蔬菜并排储存,并由同一个减速机处理。对于每种成分,你会有“数量”和“类型”字段,即“水果”或“蔬菜”。回答你的问题:是的,可以按照你想要的方式组合这三种还原剂,但是您需要编写自己的函数来完成它,而不是使用组合减速机。非常感谢您提供的详细答案。