This graph shows how many times the word ______ has been mentioned throughout the history of the program.
Vamos a hacer una aplicación de notas con Redux y vamos a empezar aquí de 0.
Voy a dejar los imports, porque los imports sí que los vamos a necesitar.
Vamos con lo primero, un node reducer.
Y en este caso, como es una aplicación de notas, vamos a pensar que el estado es un array.
Y vamos a tener un segundo parámetro, que es la action.
Vamos a hacer un action type que sea igual a new node.
Podríamos pensar que hacemos un state.push.
Como hemos dicho antes, las acciones son objetos y por lo tanto pueden tener más información aquí.
Así que vamos a poner un action.payload y luego veremos cómo rellenamos esto.
Y luego podríamos justamente hacer un return state.
Voy a hacer un return state aquí, por defecto.
Hemos dicho que un reducer lo que hace es una máquina de estado.
Tú me pasas un estado y yo te devuelvo un nuevo estado.
¿Esto está devolviendo un nuevo estado?
Esto lo que está haciendo es mutar el estado original.
El push lo que hace justamente es modificar el array original.
Para evitar esto, al state actual, que es un array vacío, imagínate la primera vez,
le vamos a concatenar el action.payload.
Y el payload ya veremos cómo lo sacamos, pero en payload vamos a necesitar tener toda la información de nuestras notas.
Ahora vamos a crear la store con create store y le pasamos el node reducer.
Por ahora vamos a ir directamente a hacer un dispatch desde fuera de nuestra aplicación.
¿Qué haríamos de dispatch?
Pues tendríamos un type que podríamos ser, bueno aquí le he puesto new node,
pero antes he puesto así node created, por ejemplo.
Este type que le vamos a pasar aquí.
Vamos a hacer un dispatch de esta acción y vamos a pasarle el payload.
Esto puede ser payload y aquí tendríamos la información que queremos que tenga nuestra nota.
Content, me encantan las clases de midudev.
Le podríamos decir el important, vamos a decir que es true y le vamos a pasar la id.
Esto lo podemos hacer tantas veces como queramos.
Me encantan las clases de midudev, pero tengo hambre.
Ya teníamos dos notas.
Esta la vamos a poner false.
Vamos a crear rápidamente nuestra app que lo que va a hacer es el state tor.getState
y este state lo que va a tener es un array con las notas.
Y ahora cada nota pues la renderizaríamos, ¿no?
Y lo que renderizamos en cada una pues vamos a hacer que sea un lead donde la key sea node.id
y dentro del lead pues tenemos la node content y podremos hacer un strong que diga que si node
es important pues le decimos que es important y si no es not important.
A ver si esto lo formateamos un poquito mejor, más o menos.
Que esto realmente lo estamos gestionando de forma manual.
Que te tienes que suscribir, tienes que hacer esto, ¿vale?
Tienes que renderizar la aplicación, de nuestra aplicación, renderizar y nos suscribimos y ya está.
Vamos a ver si esto funciona, ¿ves?
Tenemos aquí me encantan las clases de midudev, important, pero tengo hambre, jajaja, no te importan.
Que sí que están funcionando los dispatch, pero claro, no lo estamos haciendo como tal.
No tenemos en la UI una forma de actualizar, pero ya estamos viendo cómo podemos utilizar un array.
Una cosa que te tiene que dar clarísima del reducer es que los reducers llega un estado y devuelve uno nuevo.
Y también los reducers son funciones puras.
Significa que pasándole los mismos parámetros siempre tiene que devolver la misma información.
¿Qué quiere decir?
Que tú cuando incrementas el estado de uno siempre tiene que devolver dos.
Cuando tú en este estado le estás pasando un array vacío como estado y en el action le estás devolviendo que es el tipo created y que el payload es uno, siempre debería devolver la misma información.
Esto es lo que hace que tu estado sea predecible y que lo puedas testear.
¿Cómo puedes hacer que sea impura?
Si aquí este concat, yo qué sé, aparte de hacer esto, en el payload aquí pongamos el important, que esto es un math random, esto ya haría que tu función sea impura.
Porque no siempre va a tener el mismo resultado con los mismos parámetros.
Lo interesante ahora sería ver cómo podemos hacer cambiarle la importancia.
Aunque no estamos construyendo todavía la UI, porque no tiene sentido que me ponga aquí a construir la UI y perder el tiempo en eso cuando lo interesante aquí es que aprendamos Redact, nos vamos a poner con el testing.
Podríamos, por ejemplo, crear un reducers, reducers, test, así.
Este reducer que lo estamos dejando aquí en medio, así súper mal, podríamos dejarlo en un archivo suyo propio.
Así que lo que vamos a hacer aquí es tener node-reducer.js, ¿vale?
Vamos a quitar esto de aquí y lo vamos a mover aquí.
Ahora lo que vamos a hacer es exportarlo de forma que donde lo necesitemos, pues lo importamos, ningún problema.
Reducers, node-reducer, aquí ya tendríamos nuestro node-reducer, esto funcionaría bien.
Ahora además que lo hemos separado, ahora es mucho mejor a la hora de testearlo.
Vamos a escribirle un test que sea más o menos, vamos a hacer un import de node-reducer.
Justamente vamos a hacer TDD porque vamos a hacer un testing de la siguiente acción que quiero añadir.
La siguiente acción que quiero añadir, vamos a poner un describe, que es node-reducer.
Vamos a probar que devuelve un nuevo estado, new state after action with toggle importance.
Vamos a hacer que cuando cambiemos la importancia de una nota, que nos vaya a testear esto.
Podremos ver realmente cómo funciona, qué estado vamos a necesitar.
Aquí en el estado podríamos tener una nota, important false, podríamos tener aquí otra nota, content, node 2, important false.
Vale, vamos a crear nuestra acción, ¿vale?
Que el type, bueno, podemos hacer node y esto toggle importance, vamos a hacerla así, ¿vale?
Node toggle importance.
En el payload podríamos decirle la idea de qué nota es la que le tienes que cambiar la importancia.
Vamos a decir que sea la 2 para que sea tú.
Por ahora lo que vamos a hacer es tener aquí un new state.
Como tenemos el reducer, ves, en los testings sí que puede ser interesante que ejecute la función.
De forma que tenemos el node reducer y el node reducer le vamos a pasar este estado, que sería el estado que nosotros queremos comprobar,
y le vamos a pasar la acción, que es justamente esta.
Pues deberíamos mirar que el new state tenga una length de 2, ¿no?
Porque tenemos dos notas.
El new state también podríamos mirar que no haya cambiado la primera nota,
porque la primera nota, justamente esta nota de aquí, no debería ser exactamente la misma.
Solo hemos dicho que vamos a cambiarla ahí de 2.
Así que vamos a mirar state 0.
Otra cosa que podríamos hacer, bueno, pues en el new state podríamos hacer
to contain equal que sea esto, pero esto debe ser true.
Que contenga, que sean dos notas.
Que contenga la nota, la primera, la que teníamos exactamente igual,
y que contenga una nueva, pero con la importancia al revés.
Ahora podríamos ir a nuestro node reducer,
porque si ejecutamos los test, esto debería petar, ¿vale?
Porque realmente nuestro reducer no está preparado para funcionar con esta acción.
Así que lo que vamos a hacer es prepararlo.
Ya sabéis la importancia de ver los test en rojo.
Vamos a arreglar esto.
Hacer aquí un type action, que si tenemos notes barra, y aquí toggle importance,
aquí lo que podríamos hacer justamente es cómo vamos a buscar esta nota.
Aquí es una de las típicas cosas y uno de los grandes problemas que la gente se encuentra en Redux.
Entonces, cómo mantener la inmutabilidad, cómo actualizar un estado sin romper algo, ¿no?
Vamos a hacerlo regular, para que veamos que nos puede pasar el test,
pero lo estamos haciendo no de la forma correcta.
Primero recuperamos la idea del action payload,
porque si miramos la acción del payload,
le vamos a pasar la idea de la nota que queremos cambiarle justamente la importancia.
Ahora tendríamos que encontrar la nota,
así que vamos a poner node del state,
a la parte de un find de la note,
donde la note id sea igual a la id.
Así que esta nota ya la tendríamos aquí, ¿no?
Esta nota, en realidad, lo que podríamos hacer justamente es cambiarle la importancia.
Podríamos hacer esto, ¿no?
Vamos a poner, bueno, es que toggle importance.
Voy a cambiar toggle important, que parece más toggle important, toggle important.
Vale, y aquí lo que podríamos hacer es esto directamente.
Cambiarle la importancia y ya está.
Y ahora podríamos devolver otra vez el estado,
de forma que podríamos poner que la nota,
vamos a mapear este estado otra vez, ¿no?
Y decimos, vale, vamos a mapear el estado.
De hecho, esto lo podríamos haber hecho, mira,
return state.map de la nota.
Con un solo map lo puedes hacer mucho más fácil.
Si la nota .id es igual a id,
entonces haces un return de lo que sea.
Y si no, pues devuelves la misma nota.
Por ejemplo, si la id es igual a id,
aquí haces node.important igual node.important
y devuelven la nota y ya está.
Vamos a revisar lo que hacemos.
Action type, que nos pregunta el toggle important.
Recuperamos la id del action payload
y lo que hacemos es, vamos a iterar todo el estado,
porque el estado es un array de notas,
y por cada nota vamos a buscar si esa nota en la que tiene la id,
si tiene esa id, le vamos a cambiar el important,
le vamos a cambiar el valor del important
y vamos a devolver la nota.
Y si no, simplemente devolvemos la nota.
Si ves el código, lo puedes simplificar,
porque esto y esto, como están aquí repetidos,
esto lo podrías quitar,
solo hacer esto en el caso de que tengas que devolver la nota
con el important cambiado,
y si no, pues devuelve la nota y ya está.
Sea lo que sea, este if solo entra cuando es necesario
y siempre devuelve la nota.
Y una vez esto que se ha iterado,
devuelves el estado ya transformado.
Ahora voy a probar si esto funciona.
Los tests han pasado.
Lo que no me queda muy claro es si estamos mutando el objeto,
si realmente estamos haciendo lo que deberíamos hacer,
si realmente nos hemos portado bien.
O sea, he dicho que no deberíamos mutar un objeto.
Y aquí estoy haciendo un node.important.
Esto, el node es un objeto,
al hacer el punto important lo estoy mutando.
No se me ha quejado, el test ha pasado,
no parece que sea ningún problema.
¿Cómo puedo tener yo la seguridad
de que realmente no lo estoy mutando?
Porque a veces puedes tener dudas.
Ya te digo yo que aquí se está mutando,
o sea, no hay ninguna duda.
Pero el test tampoco te lo está diciendo,
no estamos haciendo un control bastante estricto de esto.
Lo que puedes hacer es instalar una dependencia de desarrollo
que se llama deep freeze.
En el test, lo que puedes hacer antes justamente
de pasar el estado es hacer un deep freeze del estado.
Lo que está haciendo este deep freeze es decirle,
esto lo vas a congelar.
Si alguien intenta mutar este objeto,
me sacas un error.
Y mira, no se puede asignar a una propiedad
que es de solo lectura,
no se le puede asignar algo.
Y es que aquí lo estoy mutando.
Ahora sí que sé que no solo la implementación funciona,
sino que me voy a asegurar que hago la correcta.
Cuando utilicéis el map,
no penséis que al utilizar un map
estáis haciendo la suficiente inmutabilidad.
Porque aunque hacéis un map
y es verdad que los elementos que estáis haciendo
los estáis devolviendo al array,
que si es un array de objetos,
los objetos los podáis mutar dentro, ¿vale?
Es otro error súper común en Redux
de que utilizas un map y dices,
ah, pues ya está, no hay ningún tipo de problema.
Para no mutar el objeto,
lo que vamos a hacer es utilizar
nuestro spread operator
que hemos visto en un montón de clases.
Lo que vamos a hacer es hacer una copia de todas las notas
y en el important lo que vamos a hacer es
node.important.
Estamos creando un nuevo objeto.
Ten cuidado también con esto
porque hay veces que aunque tú hagas esto,
si esto tiene un objeto dentro,
puedes encontrarte un montón de problemas
y a veces hay que anidar spreads dentro de spreads.
Dentro de spreads, dentro de spreads.
Esto se puede solucionar utilizando
algunas otras bibliotecas
como ImerJS y cosas así.
Ahora, ¿ves?
Ahora sí que nos pasan los tests.
Igual que podéis utilizar state.comcat,
también podéis utilizar un spread, ¿vale?
Podéis crear un nuevo array
que le decís, vale,
me vas a añadir todo lo del state
y además el action.payload.
Los dos son iguales,
un poco distintos,
uno más rendimiento que el otro,
igual uno de la transpilación
y otro no,
el que prefiráis, ¿vale?
El spread operator
vais a ver que utilizando Redux
va a ser uno de vuestros
grandes y grandes amigos.
Así que lo importante es que lo dominéis,
que lo probéis,
veáis cómo se utiliza
y ya está.
Y con esto,
pues ya hemos visto
una introducción de Redux.