Skip to content

Instantly share code, notes, and snippets.

@gamezcua1
Created July 30, 2018 04:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gamezcua1/64708bb9f86d1b8cb9a961d71cc9dfdb to your computer and use it in GitHub Desktop.
Save gamezcua1/64708bb9f86d1b8cb9a961d71cc9dfdb to your computer and use it in GitHub Desktop.
Redux reducer explained
/**
* ¿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