Redux es una solución muy popular para la gestión de estado en aplicaciones React. También trabajo mucho con esta biblioteca y en este breve artículo, quiero compartir una forma en que podemos usar la notación de objetos para verificar nuestros tipos de acción.
En la mayoría de los casos, los desarrolladores usan 2 formas comunes de iterar a través de los tipos de acción. El primer enfoque es usar la construcción if else
. Puede ser útil para reductores pequeños, donde tenemos solo una o dos condiciones. He aquí un ejemplo de tal caso:
const SAVE_USER_NAME = 'SAVE_USER_NAME'; export const reducer = (state, { type, payload }) => { if (type === SAVE_USER_NAME) { return { ...state, name: payload, }; } return state; };
Solo tenemos un tipo de acción SAVE_USER_NAME
. Y en nuestro reductor usamos la construcción if
para verificar el tipo de acción actual. Cuando es igual a verdadero, devolvemos el nuevo estado, cuando no, simplemente devolvemos el estado inicial. Este es un buen enfoque, pero no será tan bueno cuando tengamos un par de tipos de acción diferentes. En esta situación, otra solución muy popular que se usa en todas partes es la construcción switch
. Nos permite iterar a través de una gran cantidad de tipos de acción sin if else
. Ejemplo de esta solución:
const SAVE_USER_NAME = 'SAVE_USER_NAME'; const SAVE_USER_EMAIL = 'SAVE_USER_EMAIL'; const SAVE_USER_ADDRESS = 'SAVE_USER_ADDRESS'; export const reducer = (state, { type, payload }) => { switch (type) { case SAVE_USER_NAME: return { ...state, name: payload }; case SAVE_USER_EMAIL: return { ...state, email: payload }; case SAVE_USER_ADDRESS: return { ...state, address: payload }; default: return state; } };
Se ve mucho mejor que si usamos mucho else if
. Pero en mi experiencia a veces tuve que lidiar con reductores donde tenemos 40 o incluso 60 'casos'. Y, como usamos SonarQube en nuestra canalización de CI/CD, comenzó a enviar muchas alertas porque había demasiados "casos" en el bloque de switch
. Entonces, ¿cómo podemos arreglar esto?
Lo primero que podemos hacer es dividir nuestro reductor grande en varios más pequeños. Pero, ¿y si no queremos hacer esto o no tenemos suficiente tiempo? ¿Tenemos otra forma de refactorizar este reductor y quitar el switch
?
Sí, tenemos. Y aquí podemos usar objetos. Soy un gran admirador de los objetos y los mapas hash, y acabo de refactorizar la solución anterior:
const SAVE_USER_NAME = 'SAVE_USER_NAME'; const SAVE_USER_EMAIL = 'SAVE_USER_EMAIL'; const SAVE_USER_ADDRESS = 'SAVE_USER_ADDRESS'; export const reducer = (state, { type, payload }) => { const actionTypes = { [SAVE_USER_NAME]: () => ({ ...state, name: payload, }), [SAVE_USER_EMAIL]: () => ({ ...state, email: payload, }), [SAVE_USER_ADDRESS]: () => ({ ...state, address: payload, }), }; return actionTypes[type] ? actionTypes[type]() : state; };
Hemos creado el objeto actionTypes
, donde una clave es nuestro tipo de acción y el valor es una función. Luego verificamos, si existe tal clave, ejecutamos la función, de lo contrario, simplemente devolvemos el estado inicial. Personalmente, me gusta este enfoque. Se ve elegante y fácil de leer.
¿Qué piensas de esta manera? ¿Usas ese enfoque o tal vez algo más?
PD: Es mi primer artículo, así que espero que sea interesante y no me tiren tomates 😄