У событий (событий DOM или системных событий) есть отношения 1:1 с действиями? т.е. если одно событие щелчка запускает только одно действие?
Например, скажем, у нас есть страница, которая отображает таблицу из 10 строк и 2 столбца. Каждая строка имеет поле "Продукт" и поле "Сумма". Поле "Сумма" имеет вход диапазона с диапазоном [0, 10]. Пользователь может установить количество каждого продукта отдельно.
Пользователю также предоставляется 2 варианта с помощью 2 кнопок.
- Нажатие второй кнопки отключит все, кроме первого продукта в таблице (эффективно установив их значение в 0, и пользователь больше не сможет взаимодействовать с ними, чтобы установить их количество). Позвольте называть это
Option B
- При нажатии первой кнопки все Продукты после первого (по умолчанию устанавливают их количество на 1 для каждого из них), и пользователь может снова взаимодействовать с ними, чтобы установить их суммы индивидуально. Позвольте называть это
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 `````````
Состояние этого "приложения" описывается этим простым объектом
state = {
option : <String>,
products : [
{
name : <String>,
amount : <Integer>
}, ...
]
}
У нас также есть эти 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 }
}
}
Для простоты мы имеем только один редуктор.
В этом примере выбор Option B
должен иметь следующие эффекты для состояния:
- Измените
option
наB
- Задайте количество каждого
product
после первого значения0
Выбор Option A
должен иметь следующие эффекты для состояния, соответственно:
- Измените
option
наA
- Задайте количество всех
product
после первого значения1
Приращение количества продукта A должно иметь следующие эффекты для состояния:
- Увеличьте количество продукта A на 1
Каким будет правильный способ реализовать эти изменения?
a) Попросите обработчик onClick
кнопок option
выполнить следующие действия:
- Пожар a
store.dispatch(setOption(option))
- Для каждого продукта после первого пожара a
store.dispatch(setAmount(productName, amount))
(amount
= 1 для опции A, 0 для опции B)
b). Обработчик onClick
кнопок option
выполняет следующие действия:
-
Пожар a
store.dispatch(setOption(option))
И замените редуктор на
option
, а такжеamount
каждого продукта после первого на указанное количество (amount
= 1 для опции A, 0 для опции B)
Если мы идем с a), каждый случай в выражении switch (action) {}
редуктора имеет дело только с одним аспектом состояния, но мы должны запускать более одного действия из одного click
событие
Если мы идем с b), мы запускаем только одно действие из события click
, но случай для SET_OPTION
в редукторе не только изменяет option
, но также и amount
продуктов.