javascript - react - ¿Los eventos y acciones tienen una relación 1: 1 en Redux?
redux-actions (2)
No hay una respuesta general a esta pregunta, por lo que debemos evaluar caso por caso.
Cuando use Redux, debe esforzarse por mantener un equilibrio entre mantener los reductores simples y mantener el registro de acciones significativo. Lo mejor es cuando puede leer el registro de acciones y tiene sentido por qué sucedieron las cosas. Este es el aspecto de "previsibilidad" que aporta Redux.
Cuando envía una sola acción y diferentes partes del estado cambian en respuesta, es fácil decir por qué cambian más tarde. Si depura un problema, no se siente abrumado por la cantidad de acciones, y cada mutación se puede remontar a algo que hizo un usuario.
Por contra, cuando distribuye varias acciones en respuesta a una única interacción del usuario, es más difícil saber por qué fueron enviadas. Abarrotan el registro de acciones, y si hay un error en la forma en que se enviaron, el registro no descubrirá los motivos subyacentes.
Una buena regla empírica es que nunca desea dispatch
en un bucle. Esto es altamente ineficiente y, como se señaló anteriormente, oculta la verdadera naturaleza de por qué sucedió el cambio. En su ejemplo particular, recomendaría disparar una sola acción.
Sin embargo, esto no significa que disparar una sola acción siempre es el camino a seguir. Como todo, es una compensación. Existen casos válidos cuando es más conveniente disparar varias acciones en respuesta a una única interacción del usuario.
Por ejemplo, si su aplicación permite a los usuarios etiquetar productos, puede ser más conveniente separar las acciones CREATE_TAG
y ADD_TAG_TO_PRODUCT
porque, si bien en este escenario ocurren al mismo tiempo, también pueden ocurrir por separado, y puede ser más fácil escribir reductores que manejen ellos como diferentes acciones. Siempre y cuando no abuse de este patrón y no haga algo así en un ciclo, debería estar bien.
Mantenga el registro de acciones lo más cerca posible del historial de interacciones del usuario. Sin embargo, si hace que los reductores sean difíciles de implementar, considere dividir algunas acciones en varias, si se puede pensar en una actualización de UI de dos operaciones separadas que simplemente están juntas. No caigas en ninguno de los extremos. Prefiere la claridad del reductor a un registro perfecto, pero también prefiere no enviar en un bucle a la claridad del reductor.
¿Los eventos (eventos DOM o eventos del sistema) tienen una relación 1: 1 con acciones? es decir, ¿un evento de un solo clic debe activar solo una acción?
Por ejemplo, digamos que tenemos una página que muestra una tabla de 10 filas y 2 columnas. Cada fila tiene un campo Producto y un campo Cantidad. El campo Cantidad tiene una entrada de rango con un rango de [0, 10]. El usuario puede establecer la cantidad de cada producto individualmente.
El usuario también tiene 2 opciones, mediante el uso de 2 botones.
- Al presionar el segundo botón, se inhabilitará todo excepto el primer producto de la tabla (estableciendo efectivamente su Cantidad en 0 y el usuario ya no podrá interactuar con ellos para establecer su Cantidad). Vamos a llamar a esta
Option B
- Al presionar el primer botón, se habilitan todos los productos después del primero (estableciendo de forma predeterminada su cantidad en 1 para cada uno de ellos) y el usuario puede interactuar una vez más con ellos, para establecer sus cantidades individualmente. Llamemos a esta
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 `````````
El estado de esta ''aplicación'' está descrito por este simple objeto
state = {
option : <String>,
products : [
{
name : <String>,
amount : <Integer>
}, ...
]
}
También tenemos estos 4 simples creadores de acción:
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 }
}
}
En aras de la simplicidad, tenemos solo un reductor.
En este ejemplo, seleccionar la Option B
debería tener los siguientes efectos en el estado:
- Cambiar la
option
aB
- Establezca la cantidad de cada
product
después del primero en0
Seleccionar la Option A
debería tener los siguientes efectos en el estado, respectivamente:
- Cambiar la
option
aA
- Establezca la cantidad de cada
product
después del primero a1
Incrementar la cantidad del Producto A debería tener los siguientes efectos en el estado:
- Incremente la cantidad de Producto A en 1
¿Cuál sería la forma correcta de implementar estos cambios?
a) Haga que el controlador onClick
de los botones de option
haga lo siguiente:
- Fire a
store.dispatch(setOption(option))
- Para cada producto después del primero,
store.dispatch(setAmount(productName, amount))
unstore.dispatch(setAmount(productName, amount))
(amount
= 1 para la opción A, 0 para la opción B)
b) Haga que el controlador onClick
de los botones de option
haga lo siguiente:
Fire a
store.dispatch(setOption(option))
Y haga que el reductor cambie la
option
, así como laamount
de cada producto después de la primera a la cantidad especificada (amount
= 1 para la opción A, 0 para la opción B)
Si vamos con a) cada caso en la declaración switch (action) {}
del reductor trata solo con un aspecto del estado, pero tenemos que disparar más de una acción desde un click
Si vamos con b) SET_OPTION
solo una acción del evento click
, pero el caso de SET_OPTION
en el reductor no solo cambia la option
sino también la amount
de productos.
Para agregar a la excelente respuesta de Dan, cuando vas por el camino b) todavía puedes manejar partes separadas del estado como dijiste en a) forma dividiendo el reductor de raíz en otros más pequeños, como muestran los documentos de Redux . Debe dividir la gestión del estado componiendo reductores, no mediante el envío arbitrario de otras acciones. Como dijo Dan, ayuda a las acciones que expresan el por qué .