Created
July 30, 2018 04:04
-
-
Save gamezcua1/64708bb9f86d1b8cb9a961d71cc9dfdb to your computer and use it in GitHub Desktop.
Redux reducer explained
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* ¿Qué es un reducer? | |
* Como ya te había dicho el reducer tiene varias funciones que tiene que realizar | |
* 1.- Modificar el storage | |
* 2.- Siempre debe de regresar un estado del storage | |
*/ | |
/** | |
* Como ya te mencioné un reducer SIEMPRE debe de regresar un estado del storage, | |
* Esa es la razón por la que dejamos por defecto especificado cuál es el estado inicial del | |
* storage. | |
* | |
* Este storage puede ser de cualquier tipo, puede ser un Array, un JSON, un Objeto, | |
* o una variable x | |
* | |
* Y además de el estado anterior del storage necesitamos cual fue la acción que se ejecuto | |
* que viene desde una Action, EX: return { type: "AÑADIR_CARRITO", payload: producto } | |
*/ | |
export default function (state = {}, action) { | |
/** | |
* Entonces lo que viene cada vez que se dispara una ación es que entra a esta funcion y | |
* y se trae el estado ACTUAL del storage y la acción disparada por un evento en react | |
* y lo que sigue hacer es decirle al reductor QUÉ es lo que tiene que hacer dependiendo de | |
* CUÁL fue la acción disparada, para lo que generalmente se utiliza un switch v: | |
*/ | |
switch(action.type){ | |
/** | |
* Vamos a comenzar con lo que no debes de hacer. | |
* | |
* En redux, tu NUNCA debes de MUTAR el storage directamente, porque para eso son los reducers | |
* los reducers se encargan de SUSTITUIR el estado del storage por uno NUEVO(con los valores | |
* cambiados) | |
*/ | |
case "AÑADIR_CARRITO_BAD_1": | |
// Esta linea lo que haría sería acceder al valor 'producto' suponiendo de que es un arreglo | |
// y añade el producto (payload de la accion) a ese array | |
state.productos.push(action.payload); | |
// Puesto que estamos accediendo a el estado directamente y lo queremos cambiar | |
// estamos MUTANDO el estado original y crasheará | |
return state; | |
case "AÑADIR_CARRITO_BAD_2": | |
/** | |
* Entonces piensas tantito y dices, qué tal si copio el estado actual, lo meto en una | |
* variable y a esa nueva variable le meto el objeto | |
*/ | |
// creamos una nueva variable desde el state actual | |
let proximoNuevoEstado = state; | |
// Añadimos el producto de igual manera que la anterior | |
proximoNuevoEstado.productos.push(action.payload) | |
/** | |
* El pex con esto es que al copiar la variable como en la linea 50 no estamos creando | |
* un nuevo objeto que es una copia del estado, estamos copiando el puntero del objeto | |
* y se lo estamos poniendo a 'proximoNuevoEstado' por lo que si cambiamos algo en este | |
* objeto estarémos cambiando tambien el state original y por consecuente estamos | |
* MUTANDO el storage actual | |
*/ | |
return proximoNuevoEstado; | |
/** | |
* Entonces... ¿Qué wea es la mejor opción para cambiar el storage? porque pues al chile | |
* como le haces para cambiarlo sin cambiar el original... | |
* | |
* La primera opción es copiar el estado anterior y crear un objeto completamente nuevo | |
* sin el mismo puntero del objeto, de esta manera no estaremos copiando el objeto | |
*/ | |
case "AÑADIR_CARRITO_GOOD_1": | |
// creamos el nuevo objeto copiandolo, (funcion copiarObjeto al final del reducer) | |
let nuevoEstadoMamalon = copiarObjeto(state) | |
// Y creamos un nuevo objeto en el que mezclamos los productos anteriores, | |
// y el producto nuevo que fue añadido | |
let prodAñadido = Object.assign({}, state.productos, action.payload); | |
// Combinamos este nuevo objeto de productos añadidos con el estado anterior | |
// de esta manera estarémos añadiendo el nuevo objeto que contiene el producto añadido | |
// a una variable llamada 'productos' la cual será combinada con el estado anterior del storage | |
nuevoEstadoMamalon = Object.assign({}, nuevoEstadoMamalon, {productos: prodAñadido}) | |
return nuevoEstadoMamalon; | |
/** | |
* Sin embargo hay una manera más fancy de hacer todo este pedo, y sin la necesidad de copiar | |
* el objeto como tal, y esta es usando la funcion ode las lineas 75 y 79 assign | |
* | |
* El objeto primitivo de JS 'Object' contiene una funcion llamada 'assign' que se encarga | |
* de mezclar objetos de una manera más facil EX: | |
* | |
* let obj1 = {a:'a'} | |
* let obj2 = {b:'b'} | |
* let ab = Object.assign({}, obj1, obj2) // -> {a:'a', b:'b'} | |
* | |
*/ | |
case "AÑADIR_CARRITO_LIKE_A_PRO": | |
// Puesto que Object.assign nos regresa un objeto, pues lo regresamos de putaso, easy, | |
// pa que escribimos más? | |
// Combinamos el estado anterior, con un nuevo objeto que contiene la variable 'productos' | |
return Object.assign({}, state, { | |
// De manera gracios productos necesita ser combinado con un nuevo objeto que viene de la | |
// acción disparada, por lo que tambien necesitamos hacer un assign | |
// pero en esta vez combinarémos el los productos actuales, y el producto añadido | |
// esta acción nos regresará un objeto que contendrá los productos en una variable llamada | |
// productos | |
// y esta nueva variable será mezclada con la variable ya creada (o no) del estado | |
// En otras palabras "metemos un producto a la lista de productos:v" | |
productos: Object.assign({}, state.productos, action.payload) | |
}) | |
// Y como SIEMPRE tenemos que devolver el estado del storage pues | |
// en caso de no haberse disparado ninguna acción se regresa el state por defecto | |
default: | |
return state; | |
} | |
} | |
//Funcion mamaolna para copiar objetos | |
function copiarObjeto(mainObj) { | |
let objCopy = {}; // objCopy will store a copy of the mainObj | |
let key; | |
for (key in mainObj) { | |
objCopy[key] = mainObj[key]; // copies each property to the objCopy object | |
} | |
return objCopy; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment