Dim*_*nis 32 javascript events action redux
事件(DOM事件或系统事件)与操作有1:1的关系吗?即单击事件应该只触发一个动作?
例如,假设我们有一个显示10行2列表的页面.每行都有一个Product字段和Amount字段.Amount字段的范围输入范围为[0,10].用户可以单独设置每个产品的数量.
通过使用2个按钮,用户还可以选择2个选项.
Option B
Option A
.Option A selected: | PRODUCT | AMOUNT | |------------------|-----------| | Product A | - 4 + | | Product B | - 0 + | | Product C | - 4 + | ```````````````````````````````` _________ | Option A| OPTION B ````````` Option B selected: | PRODUCT | AMOUNT | |------------------|-----------| | Product A | - 4 + | | Product B | Disabled | (Amount == 0) | Product C | Disabled | (Amount == 0) ```````````````````````````````` _________ OPTION A | OPTION B| ````````` Option A selected again: | PRODUCT | AMOUNT | |------------------|-----------| | Product A | - 4 + | | Product B | - 1 + | | Product C | - 1 + | ```````````````````````````````` _________ | Option A| OPTION B `````````
这个'app'的状态由这个简单的对象描述
state = {
option : <String>,
products : [
{
name : <String>,
amount : <Integer>
}, ...
]
}
Run Code Online (Sandbox Code Playgroud)
我们还有这4个简单的动作创建者:
function setOption(option) {
return { type : 'SET_OPTION', option : option};
}
function incAmount(productName) {
return {
type : 'INCREMENT_AMOUNT',
product : productName
}
}
function decAmount(productName) {
return {
type : 'DECREMENT_AMOUNT',
product : productName
}
}
function setAmount(productName, amount) {
return {
type : 'SET_AMOUNT',
payload : { product : productName, amount : amount }
}
}
Run Code Online (Sandbox Code Playgroud)
为简单起见,我们只有一个减速器.
在此示例中,选择Option B
应对状态具有以下影响:
option
到B
product
之后的每个数量0
选择Option A
应分别对状态产生以下影响:
option
到A
product
之后的每个数量1
增加产品A的数量应对状态产生以下影响:
实施这些变化的正确方法是什么?
a)onClick
让option
按钮的处理程序执行以下操作:
store.dispatch(setOption(option))
store.dispatch(setAmount(productName, amount))
(amount
对于选项A = 1,对于选项B为0)b)onClick
让option
按钮的处理程序执行以下操作:
火a store.dispatch(setOption(option))
并且将减速器option
和amount
第一个之后的每个产品的更改更改为指定的量(amount
对于选项A = 1,对于选项B为0)
如果我们考虑a)switch (action) {}
减速器声明中的每个案例只处理一个州的一个方面,但我们必须从一个click
事件中触发多个动作
如果我们选择b)我们只从click
事件中触发一个动作,但SET_OPTION
减速器中的情况不仅会改变产品option
而且会改变amount
产品.
Dan*_*mov 42
这个问题没有一般性答案,所以我们必须根据具体情况进行评估.
使用Redux时,您应该努力在简化Reducer和保持action log有意义之间保持平衡.最好是你可以阅读行动日志,这是事情发生的原因.这是Redux带来的"可预测性"方面.
当您调度单个操作,并且状态的不同部分响应时,很容易告诉他们为什么稍后更改.如果您调试问题,您不会被操作量所淹没,并且每个突变都可以追溯到用户所做的事情.
通过constrast,当您在响应单个用户的交互派遣多个动作,这是很难说为什么他们被分派.它们使操作日志变得混乱,如果调度它们的方式有误,则日志不会发现根本原因.
一个好的经验法则是你永远不想dispatch
循环.这是非常低效的,正如上面提到的,掩盖的真正性质,为什么变化发生了.在您的特定示例中,我建议触发一个动作.
然而,这并不意味着发射单一动作始终是要走的路.像所有事情一样,这是一种权衡.在有效的情况下,响应单个用户交互来触发多个动作更方便.
例如,如果您的应用程序允许用户标记产品,则分离CREATE_TAG
和ADD_TAG_TO_PRODUCT
操作可能更方便,因为虽然在这种情况下它们同时发生,但它们也可能单独发生,并且可以更容易地编写将其处理为不同的行动.只要你不滥用这种模式并且不在循环中做这样的事情,你应该没事.
保持操作日志尽可能接近用户交互历史记录.但是,如果它使得reducers实现变得棘手,可以考虑将一些动作拆分成几个,如果UI更新可以被认为是恰好在一起的两个单独的操作.不要陷入任何一个极端.将减速机的清晰度提高到完美的日志,但也不希望在循环中调度到减速器的清晰度.
归档时间: |
|
查看次数: |
4525 次 |
最近记录: |