This graph shows how many times the word ______ has been mentioned throughout the history of the program.
En la clase de hoy te voy a enseñar una alternativa muy interesante a Redux,
porque es mucho más sencillo y por un montón de cosas.
De hecho, te voy a hacer ahora un croquis para que entiendas un poco la diferencia.
Vamos a ver rápidamente dos códigos comparándolos
para que veas también lo positivo y lo negativo de esta nueva solución
que se llama Zustan y vamos a hacer desde cero esta aplicación
donde sería como un JavaScript quiz,
donde vamos a tener un montón de preguntas y tal
y al final le tenemos que decir si ha ganado o no ha ganado,
cuántas ha adivinado y todo esto.
Así que eso es lo que vamos a hacer.
Os voy a explicar primero lo que vamos a ver.
Bueno, ya sabéis que existe Redux Toolkit.
Si no sabes lo que es, pues no te preocupes.
Redux es un gestor de estado global y no solo funciona con React,
en realidad funciona con cualquier cosa.
Y está bastante bien, pero aquí tenemos cosas que te pueden gustar o no,
que es opinionado.
Opinionado significa que te viene con un montón de cosas ya preconfiguradas
y que te tienes que empezar a aprender porque si no, no sabes por dónde viene.
Redux tiene un montón de conceptos, las actions, los reduces,
un montón de cosas para entender, los action creators, para saber cómo funciona.
De hecho, Redux no solo estamos hablando de una biblioteca,
es que es como un conjunto de reglas, diría yo, y todo.
O sea, van mucho más.
Claro, por eso el uso de la guía, pues fíjate que aquí son un montón,
un montón de explicaciones y tal.
Es bastante complejo, la verdad.
Para principiantes es bastante, bastante complejo.
Las cosas como son.
¿Qué vamos a ver hoy?
Bueno, pues vamos a ver una alternativa que se llama Zustan.
Zustan es tremendo porque es un manejador de estado.
Este sí que está pensado especialmente para React,
que es absurdamente sencillo.
Es muy, muy, muy sencillo.
Ya ves que tienes aquí import, create, tú creas una store
y ya puedes utilizar una store.
En estas pocas líneas de código tienes un estado global.
Pero entonces la pregunta del millón es, bueno,
pero ¿cuál es la ventaja entre uno y otro?
Voy a hacer un croquis rápido de por qué este oso es vuestro mejor amigo
entre estos dos y las diferencias de cuándo usar uno, cuándo usar...
Bueno, cuándo usar uno u otro, ¿no?
Pero vamos a ver un poco las ventajas de cada uno y tal.
¿Qué es lo malo que tiene Redux?
A ver, que tiene mucho boilerplate, ¿vale?
Así que le vamos a poner aquí un menos.
Mucho boilerplate.
Mucho boilerplate.
¿Esto qué quiere decir?
Pues que para crear algo en Redux ya tienes que generar mucho código
y siempre se va repitiendo el código.
Tienes que crear las acciones, tienes que hacer esto,
tienes que crear un montón.
En verdad que con Redux Toolkit ha mejorado bastante,
ha mejorado, pero aún así sigue siendo necesario.
Fíjate todo lo que necesitas.
Configurar la store, crear el reducer, crear la acción,
crear el slice, para temas asíncronos tienes que crear esto.
Hay un montón, pero un montón de cosas que tienes que hacer.
Así que tienes que generar mucho código.
Y esto se le llama boilerplate.
También lo que ocupa.
Otra cosa mala es que esto ocupa unos 20Ks más o menos, ¿vale?
Son unos 20Ks.
Claro, si te interesa el rendimiento web, pues lo deberías saber.
Tienes que sumar React Redux.
React Redux.
Este es uno, que son 5Ks.
Redux, que esto sería vacío, ¿vale?
Y luego tendríamos, no me acuerdo cómo se llama el paquete,
pero habría que sumarlo también.
A ver si lo encuentro por aquí.
Ta, ta, ta, este.
Redux, este de aquí.
Que deben ser unos 12 o algo así, ¿vale?
13.
Unos 20Ks.
Más o menos.
Sumándolo todo, unos 20Ks.
Si no llega, pues un poquito por aquí, un poco por acá.
20Ks, ¿vale?
También que es complicado para principiantes.
Complicado para principiantes.
Porque hay que aprender muchas cosas, muchos conceptos.
No es fácil empezar de cero.
Tienes que leer bastante tertulia para una persona que no sabe absolutamente nada.
Se puede liar.
De hecho, me lo está diciendo en el chat.
¿A que sí?
Que alguien me lo dice.
Mira, es complicado, sí.
Me lo está diciendo Jota.
Mucha gente que ya sabe Redux dice, pues si es súper fácil.
Claro, pues ya sabe Redux.
Una vez que ya sabe Redux, como está tan opinionado, hay que seguir unos pasos A, B, C y te sales solo.
Pero para empezar, no es tan fácil.
Mira, a mí me mata Redux.
A mí me costó bastante.
Es complejo.
Yo no he podido con Redux.
O sea, imagínate.
Como veis, es complicado para principiantes.
Mucho código para pequeños cambios.
Esto también lo tendríamos.
Muchos conceptos.
Y opinionado.
¿Qué significa opinionado en el desarrollo de software?
Opinionado es normalmente lo que hacen los frameworks.
Que tienen como una opinión que te obligan a seguirla para poder utilizarlo.
Por ejemplo, Next.js es opinionado porque te dice cómo tienes que crear las rutas para poder utilizarlo.
Redux es opinionado porque te está diciendo cómo tienes que actualizar el estado y qué estructura exacta tienes que seguir.
Entonces es muy difícil salirte de esa cuadrícula porque tienes como una opinión muy fuerte.
Que esto no significa que sea algo malo.
Esto no es malo.
Que algo sea opinionado no es malo.
Pero en Redux es verdad que esto es un poco problemático a veces.
Sobre todo para hacer algo asíncrono.
Que te obliga a tener que seguir lo de async, async y no sé qué, no sé cuánto.
Y es complejo.
Ese es el problema.
Pero que sea opinionado per se no tiene por qué ser algo malo.
Simplemente es una diferencia.
¿Para dónde lo utilizaría yo?
¿Para dónde utilizaría yo esto?
Redux yo lo usaría para proyectos medianos pero tampoco muy grandes.
¿Vale?
¿Por qué?
Porque para proyectos muy, muy, muy grandes ya normalmente se debería utilizar algo mejor como Relay, Apolo.
Para proyectos muy grandes estoy hablando de un Facebook.
¿Vale?
Un Netflix.
Cosas muy, muy, muy grandes.
Porque no lo gestiona bien.
O sea, tener todo el estado global en Redux es muy complejo.
Tienes que escribir mucho código.
Pero para proyectos medianos, o sea, ni pequeños ni muy grandes.
¿Sabes?
Mediano-grande.
Podríamos decir medianos, poco grande.
Poco grande.
Yo lo usaría ahí.
Algo positivo que yo le veo, lo voy a poner también ya que me parece positivo.
Positivo.
Positivo es la inmutabilidad por defecto.
Esto significa que podéis mutar los datos súper fácil.
O sea, no tenéis que hacer copias y no sé qué.
Bueno, esto puede ser algo positivo aunque si estás acostumbrado tampoco a nada del otro mundo.
Esto sería Redux.
¿Ok?
Venga, vamos con Zustan que es el que hoy te voy a comentar.
Lo vais a ver claramente, pero Zustan es muy simple.
Muy simple.
Es simple hasta el punto que no tiene ni provider.
O sea, y ahora lo veréis cuando hagamos el código.
¿Vale?
No tiene configuración tampoco.
Sin configuración.
Sin configuración.
No tienes que configurar.
No tiene boilerplate.
Cero boilerplate.
Es que tiene el boilerplate mínimo.
O sea, es que no es imposible ya.
O sea, además lo que ocupa.
O sea, es que ocupar.
¿Cuánto dices que ocupa?
Ocupa un K.
O sea, 19 Ks menos.
Un K.
Y si no me creéis, porque a lo mejor decís.
Ah, cómo se pasa este chico.
¿Cómo va a ocupar solo eso?
¿Cómo va a ocupar solo eso?
Te vas aquí.
Pones Zustan.
1,1.
Perdón.
Os he engañado.
1,1.
Minificado y decipeado.
Que es lo mismo que he visto de Redux.
Que eran 20.
¿Vale?
A veces puede ser un poco más.
Bueno, también es verdad que había puesto más o menos.
Más o menos.
Vamos a ponerlo.
Más o menos un K.
No está nada opinionado.
No tiene...
No hay opiniones.
O sea, no opiniones.
No está opinionado.
Ya veréis si esto es bueno o malo.
Lo malo para la gente que esto le pueda preocupar es el hecho de que es...
Hay que usar mutabilidad.
O sea, hay que hacer copias.
Aunque esto veréis que tiene una cosa positiva también.
Ya lo veréis.
¿Cuándo usaría yo esto?
Esto lo usaría...
Lo usaría...
Lo usaría siempre que pueda.
Siempre que pueda.
Básicamente.
¿Por qué?
Porque es extremadamente sencillo.
Escala muy bien.
Y puede separarlo ad infinitum de una forma muy, muy cómoda.
Y sustan para la gente que dirá...
Ostras, ¿y dónde está entonces el contexto?
El React Context.
El React Context, en este caso...
No voy a meter todas las comparaciones.
Pero esto habría que usarlo...
¿Cuándo habría que usar React Context?
Para cosas que cambian poco o nada.
¿Vale?
Como por ejemplo, el estado del usuario.
El tema de la web.
Oscuro, claro.
¿Vale?
Oscuro, claro.
Que estas cosas también las puedes hacer con Zustan.
¿Vale?
Estas cosas las puedes hacer con Zustan.
¿Pero cuándo tiene sentido React Context?
Para esto.
No tiene sentido para cuando tenemos estados globales ahí complejos.
¿Vale?
Ya no tiene sentido React Context.
Se queda muy, muy corto.
Y además tiene muchos problemas de rendimiento.
¿Cuándo no se puede usar Zustan?
No lo usaría.
No lo usaría para aplicaciones muy grandes.
Y para todo el estado global.
Por ejemplo, aquí seguramente podríamos mirar de utilizar...
Si es muy grande, pues lo mismo.
Apolo, Relay, cosas así.
Así que...
Y también para evitar ProDrieling.
Esta es súper bien.
Esta sería un poco la diferencia entre Redux, Zustan y un poco React Context.
¿Vale?
Para que lo tengáis claro.
Lo primero, os quiero enseñar...
Tengo por aquí apuntado.
Os voy a enseñar un poco para que lo veáis rápidamente.
¿Vale?
La diferencia en código, que también es interesante.
Tenemos Redux.
Esto sería un contador de Redux.
Que me lo he encontrado por ahí.
Esto no lo he hecho yo ni siquiera.
Esto es un contador de Redux.
¿Vale?
Muy sencillo.
Muy sencillo.
Donde puedes incrementar, decrementar y añadir número de...
O sea, quiero añadir dos, lo que sea.
¿Vale?
Funciona bien.
Entonces, si miramos un poco cómo es la Store, nos encontramos...
Bueno, creo que esto sería...
Esto, espérate.
Porque la Counter ni siquiera...
Ni siquiera esto...
Ah, sí.
Vale.
Es que está aquí la configuración del Store.
Vale.
Es que lo he puesto todo en la misma línea.
Vale.
Tendríamos que configurar la Store.
Que crear el Slice.
Que es como el trozo de nuestro estado.
Esto lo explicamos en una clase anterior de este mismo curso.
Pero, bueno.
No hace falta que sepas lo que es.
Es solo que veas un poco como funcionaría.
Tienes que darle un nombre al Slice.
Tienes que tener el estado inicial aquí.
Luego indicarle los Reducers.
Tienes que saber que es un Reducer.
Aquí veis que esto es inmutable.
¿No?
Que está haciendo como que puede mutarlo.
Y tiene inmutabilidad.
Porque internamente utiliza un proceso para actualizar el estado de forma muy sencilla.
Que esto puede ser algo positivo.
¿Vale?
Pero luego, fijaos.
Tenéis que exportar todas las acciones.
Tenéis que acceder a Slice.actions.
Aquí hay un selector del Count para extraer del estado el Value.
Y tenéis que configurar la Store con el Reducer, el Counter y todo esto.
¿No?
Y esto es un ejemplo bastante sencillo.
Unas 30 líneas de código.
Y además, en la aplicación tenemos que traernos el Provider.
Tenemos que traernos la Store.
Y tenemos que envolver toda nuestra aplicación con este Provider.
¿Vale?
Esto sería rápidamente para que veáis cómo funcionaría el tema de Redux.
¿Vale?
Ahora vamos a ver cómo sería lo mismo, pero en Zustan.
Este sería el mismo ejemplo, pero con Zustan.
Fijaos aquí que está feliz, como una perdiz y con la lengua afuera, el osito.
Pues, si miramos la Store de Zustan, es esto.
Creamos con Zustan.
Creamos un Custom Hook.
Porque ya está pensado 100% a React.
Creamos un Custom Hook que se llama Use Counter Store.
Y le decimos, créame.
¿Vale?
Y le pasamos aquí un Callback que recibe como primer parámetro el Set,
que será la forma de actualizar el estado.
Y esto ya devuelve directamente un objeto.
Donde tenemos, por un lado, voy a añadir comentarios.
Ya puedes ver que es menos de la mitad el código, menos de la mitad.
Pero, bueno, aquí tendríamos el Initial State o el State.
Esto sería el estado, que por inicio es un cero.
Y aquí tendríamos las Actions, entre comillas, ¿no?
Para incrementar, para decrementar, para tal.
Fíjate, este ejemplo, no sé por qué lo tenía así, pero esto no es necesario.
Esto no hace falta hacerlo.
Porque una cosa muy chula que tiene Zustan es que siempre actualiza el estado como si lo estuviese extendiendo.
Así que, por defecto, si tuvieses aquí otro estado, otro estado, ¿vale?
Y tú pones False, tú no tienes que estar constantemente poniendo aquí punto punto State para llevarte el resto del State.
Esto no hace falta.
Ya lo hace automáticamente, ¿vale?
Así que aquí estaríamos diciendo, vale, set, aquí le llega el State y incrementamos en uno, decrementamos en uno y aquí podemos hacer un Increase By Value.
Ya está.
Esto es todo lo que hay que hacer.
Ahora, lo más sorprendente, que esto sí que te va a volar la cabeza.
Es que, ¿te acuerdas que en Redux teníamos que hacer el Provider, envolver nuestra aplicación y tal?
Fíjate en esto.
Mira, quitamos esto porque esto es el Provider de Redux.
Quitamos esto, quitamos esto, ¿vale?
Quitamos esto, ¿vale?
Fíjate, sin ningún tipo de Provider está funcionando.
Magia.
No necesitas ni siquiera envolver tu aplicación con un Provider.
No necesitas esto ni siquiera.
Y esta es una de las grandes magias que tiene Zustan.
Que lo único que tienes que hacer para empezar a generar un estado global es esto.
Creas un archivo, le llamas como tú quieras llamarle, creas esto, creas el Store
y creas un Custom Hook.
Y este Custom Hook lo utilizas donde tú quieras.
En este caso, vamos aquí.
Y aquí, pues, decimos Import, Use Counter Store.
Y aquí extraemos lo que queramos utilizar, ¿vale?
Aquí veremos una de las cosas más polémicas que sí que te te Zustan.
Que para sacar cada cosa, aunque se puede hacer de diferentes formas, que luego lo veremos,
pero para extraer una cosa, si quieres evitar que haya re-renderizados innecesarios,
tendrías que extraerlo por separado.
Pero también podríamos, para que la gente no se asuste, podrías hacer esto también, ¿eh?
Increment, decrement, increase by value.
Podrías sacar todo esto del Use Counter Store, el Set State,
y aquí, pues, podría sacar Set Count, Set Increment, que quedaría todavía más claro.
Y aquí, la verdad es que daría igual, porque total, incremento, ¿vale?
Y esto lo podrías sacar de una, ¿vale?
Lo sacarías de una y esto funcionaría exactamente igual, ¿eh?
O sea, para que veas que funciona.
Ya está.
O sea, sacarías de la Store lo que quieres utilizar, lo que quieres leer,
o lo que quieres llamar, ya sean acciones, o sea, ya sean acciones,
o ya sea que quieres leer del estado.
Fíjate la diferencia con Redux, que cuando tú querías llamar algo,
sí, hacías el Use Selector este, pero luego tienes el Dispatch.
O sea, ya tienes que utilizar dos Cartoon Hooks.
Y además, para hacer el Dispatch, tienes que llamar a cada una de las acciones.
O sea, Dispatch, llamar a la acción.
Fíjate qué complicado, complicado es este onClick a la hora de incrementar.
Y es súper imperativo, porque tienes que decir, vale,
haz un Dispatch y entonces ejecuta el increment,
y entonces, ¿sabes? Es como mucho más bestia, ¿no?
Pero fíjate aquí que aquí le digo, no, no, ejecuta el increment.
Y aquí en el onClick le pasas el increment, punto.
Y ya está, ni Dispatches ni nada, simplemente funciones.
Estoy usando Zusta en un proyecto, pero no entiendo por qué al llamar al Use Store
hay que pasarle el State, el Use Store.
A ver, ¿por qué hay que pasarle el State aquí?
Porque no tienes otra forma, porque es la forma de leerlo.
De hecho, si por lo que sea no leyeses el State, no pasa nada.
Tú imagínate que el increment haces esto.
Pues no pasa nada, no hace falta que le pases el State.
Lo que pasa es que, claro, va a 100 directamente.
Pero si quieres leer el State, te lo pasa por parámetro.
Ya está, punto.
O sea, te lo pasa por parámetro y así tienes una forma de leerlo.
Ya está, para eso te lo pasa, pero no es necesario pasarlo.
Lo recibes, si lo quieres usar bien, bien.
Y si no, ya está.
Bueno, pues esos serían los dos ejemplos que os quería enseñar.
Y ahora, pues sí, vamos a crear nuestra aplicación desde cero.
Así que vámonos para aquí, vámonos para acá, vámonos, tú, tú, tú.
Vamos a aplicación y vamos a crear con Bit, que por cierto, vamos a utilizar la nueva versión de Bit, lo cual está súper bien.
Está súper bien.
La 4.3 que dicen que va súper, súper rápido.
Vamos a darle.
Procedemos y vamos a poner aquí JavaScript Quiz, porque vamos a crear esta aplicación desde cero y paso a paso.
Esta aplicación que además, pues mira, está súper bien porque así la podéis añadir en vuestros porfolios.
Es una aplicación bastante bonita.
La podéis mejorar muchísimo y que puede quedar súper bien.
Creamos el quiz.
Lo vamos a utilizar con React y con TypeScript más SWC.
No te preocupes por el TypeScript porque si no sabes, lo poco que vamos a utilizar se entiende muy fácil.
No hay nada raro.
Se entiende muy fácil, ¿vale?
SWC es una alternativa a Babel y sirve para transpilar el JavaScript.
Para que así lo pueda transformar a JavaScript que entiendan todos los navegadores.
Venga, pues hacemos en MPM Run Depth y aquí ya empezamos con nuestro proyectito, ¿vale?
Este va a ser nuestro proyectito.
Voy a cerrar.
Bueno, recuerdo para toda la gente que ha entrado.
Aquí tenéis todas las clases y todo el código que estamos haciendo semana tras semana en este curso práctico de React.
Que ya tenemos un montón de proyectos.
Tenemos 12 proyectos y hoy estamos haciendo el número 13.
Voy a abrir aquí el navegador.
Ahí el navegador, el editor.
Vale, vamos a instalar unas cuantas cosas porque vamos a utilizar Material UI.
Que muchas veces me lo habéis pedido.
Utiliza Material UI.
Hoy digo que voy a utilizar Material UI y entonces toda la gente se me pone a decir que utilice Chakra.
Siempre vais a tener alguno que queréis utilizar y no sé qué.
Pero hoy vamos a intentar utilizar Material UI porque me lo habéis pedido un montón.
Material UI, para que no lo sepas, es un catálogo de componentes que está basado en Material UI.
Se llama MUI, yo le llamo Material UI, pero se supone que se llama MUI y está basado en Material UI de Android.
Así que visualmente vas a ver que se parece muchísimo.
La instalación ya nos la dan por aquí.
Mira, para que me pedía un curso de PNPM.
Mira, aquí me dice NPM install y que hay que instalar todas estas cosas.
Vale, pues nos lo copiamos.
Y aquí hacemos esto y ponemos una P al principio.
¿Has visto?
Increíble.
Es súper fácil.
Pues ya tendríamos aquí esto instalado.
Tendríamos que instalar más cosas.
Por ejemplo, se le puede instalar el Font Source, el robot, ¿vale?
Que es la fuente que utiliza Material UI.
Y también le vamos a instalar los iconos, ¿vale?
Vamos a instalar los iconos.
Con esto tendríamos todas las instalaciones.
Uy, espérate, algo escrito mal.
Ah, es que he puesto robot y es roboto.
Roboto, ¿no?
Venga.
Ahora sí.
Ahora sí que lo encuentra.
Ahora sí.
Vale.
Con esto estamos instalando los iconos de Material UI y la fuente típica que es la de roboto.
Así que volvemos a nuestro proyectito.
Y lo primero que vamos a hacer, ya sabéis, es que hemos creado muchos proyectos de bit desde cero.
Pero nos ha generado todo esto.
Una cosa nueva es que ahora te pone el inter.
Me parece un detallazo, la verdad.
Lo malo es que creo que, ¿ves?
No termina de funcionar bien, ¿no?
Porque veis que aquí no me está quitando...
O sea, como que le da igual los semicolons.
Como que le da igual si pone semicolon o no pone semicolon.
A ver si pongo más de uno.
¿Ves?
Si pongo más de uno, entonces sí que se queja.
Pero como que no tiene opinión sobre si utilizar semicolons o no utilizar semicolons.
Y también de si no utilizas cosas.
A ver si quitamos todo esto.
Vale, sí.
Aquí tiene warnings de que no ha utilizado.
Bueno, bueno.
Bueno, no está mal.
No está mal.
Igual creo que le voy a instalar en un momento el que me gusta a mí, que es test estándar.
Que esto se configura en un momento.
Test estándar al final es un conjunto de reglas para trabajar con TypeScript y con React.
Y que ya te viene con un montón de reglas preestablecidas y que a mí me gusta bastante.
Así que aquí en el slint.rc vamos a poner aquí...
Hostia, lo malo es que me va a hacer...
Bueno, no pasa nada.
No modules.ts.standard.slint.rc.json.
Que tendré que desactivar algunas.
Algunas rules que tiene que no me gustan las tendré que ir quitando.
Algunas de promesas y tal.
Pero bueno, las iremos quitando juntos y ya está.
Y lo que sí que se va a quejar seguramente esto cuando vengamos aquí.
Vale, a ver ahora.
Lo he instalado, ¿no?
Sí que lo he instalado, ¿no?
Este es estándar.
Es que veo que todavía no le gusta.
Open slint output.
¿Ves?
Aquí, identify expected.
No, no me lo está pillando.
¿Qué ha pasado?
¿Qué he hecho mal ya?
Hola, voy llegando.
Tienes un parse error.
Ah, vale.
Ahora sí.
Ahora sí que...
Ahora está bien.
Vale.
Ahora está bien.
Es normal que se queje porque necesita un pequeño detalle.
Esto.
Vale.
Necesitamos también ponerle aquí en los parser options, si no me equivoco, el tema de dónde tenemos el proyecto.
¿Vale?
Nada.
Esto es un momentito.
Eh, te, te, te.
Pars options project.
Vale.
Pues pars options.
Aquí en project le vamos a poner que el proyecto está en tsconfig.json.
Y en el tsconfig.json le tenemos que decir que incluya el archivo .slintrc.cjs.
Porque si no, también se quejará.
¿Vale?
Y a ver ahora.
Vale.
Ahora ya está.
Ya está funcionando.
Veis que ahora sí que me pone extra semicolon.
O sea, que ya está configurado.
No te preocupes de que digas, no, es que me he perdido.
No te preocupes.
Voy a subir este archivo y luego lo puedes, te lo puedes copiar y ya está.
Y ya, entonces, ¿qué más da?
Pero veis que hay algunas reglas que no me gustan.
Por ejemplo, esta que hay que ponerlo del TypeScript explicit function return type.
Hay un montón de reglas que no me terminan de gustar.
Pero, bueno, las podemos ir desactivando conforme las vamos encontrando y ya está.
¿Ok?
Vale.
Pues ya tendríamos aquí nuestra aplicación vacía, obviamente.
Vamos a poner por ahora el JavaScript quiz este.
Y vamos a importar las fuentes primero.
Vamos a importar por aquí las fuentes.
Las voy a poner en el main.
¿Vale?
Vamos a poner aquí en el main.
Voy a importar todas las fuentes.
Lo hago un poco a saco porque no es necesario.
Voy a quitar esto también de stream mode, que no lo necesitamos.
Y lo dejamos esto por aquí.
Vamos a ver cómo va quedando nuestra aplicación, aunque está un poco verde.
Vale.
JavaScript quiz.
Me gusta.
Como queremos hacer algo así, pero lo vamos a hacer mejor, obviamente.
Vamos a hacerlo mejor.
Así que voy a buscar el logo de JavaScript.
En un momento voy a crear el icono.
A ver, midu.
Midu, midu.
Logo es su eje.
Es que yo lo tenía.
Yo lo tengo en mi web y sé que...
Ah, ¿ves?
¿Ves?
MiduDev.
Este, este.
Este.
Este logo de JavaScript.
Y nos venimos aquí y creamos un componente que sea javascriptlogo.tsx.
¿Vale?
Export const javascriptlogo.
¿Vale?
Y esto...
Vamos a hacer esto así, más o menos.
Y ahora lo hacemos un poquito más pequeño.
Yo que sé...
48, ¿vale?
48, 48.
Venga.
Nos vamos aquí a la aplicación y lo primero que vamos a hacer es el header.
O lo más básico de nuestra aplicación.
Vamos a ponerlo todo en un main.
Aunque esto...
Un poco polémico.
Vamos a empezar a utilizar alguno de los componentes de Material UI.
Hay un montón de componentes.
No los termináis.
Lo podéis ver aquí.
¿Veis?
Autocompletes, botones, listas, tipografías, dividers, chips.
Hay un montón.
Y está bastante bien la documentación.
¿Veis?
Aquí hay, por ejemplo, el de chip, que está bastante bonito.
El de progreso.
Mira.
Un progreso, por si queréis utilizarlo en la aplicación.
Hay un montón.
O sea, no los acabáis.
¿Cuál queremos utilizar nosotros?
El container.
Vamos a ponerle un container que, como máximo, sea SM.
Me parece bien.
Esto lo vamos a envolver en el container.
Y aquí este H1, a ver...
Tiene tipografía, ¿vale?
Tiene uno que se llama typography.
¿Ves?
Este.
Y tú le puedes decir qué variante quieres utilizar.
Y, además, qué componente es el que tienes que renderizar.
O sea, esto sería visualmente que se vea como un H2, pero que renderice un H1.
Y ahora te lo enseñaré para que lo veas más claro.
Y vamos a poner aquí también un stack.
Que el stack sería como una forma de agrupar elementos de...
¿Cómo sería?
¿Cómo es la traducción de stack?
A ver si alguien me la dice.
¿Pila?
No.
Como apilar, ¿no?
Sí, mira, ya me están diciendo.
Pila, pila.
Pues, sí.
Sería como apilarlos.
Lo que pasa es que tú puedes apilar las cosas en horizontal o en vertical.
Bueno, pues, en este caso lo que le podemos decir es en qué dirección queremos apilarlos.
Entonces, es mucho más fácil que pensar en flex, pero en realidad está utilizando flex por dentro.
Entonces, queremos apilarlos como si fuese una fila.
Le dejamos una separación de dos.
Y alineamos los elementos en el centro.
Y justificamos...
Justify...
No sé por qué...
Ah, porque stack no lo he importado.
Espérate.
Ahora sí.
¿Vale?
Justify el content en el center también.
¿Vale?
Y así vamos a poner aquí al lado el JavaScript logo.
Al lado del H1 este...
Bueno, es que este he puesto un H1 aquí, que no tiene mucho sentido.
Bueno.
También lo podríamos...
O sea, no sé por qué he puesto el typography por fuera y tal.
Para que el H1 esté dentro del logo.
Bueno, lo podríamos poner al revés.
O sea, podríamos poner esto aquí.
A lo mejor tiene un poco más de sentido.
Y ya está, ¿no?
Podríamos hacer esto, por ejemplo.
Vamos a ver más o menos cómo va quedando nuestra aplicación.
Por algo se tiene que empezar.
Es trabajo...
Es trabajo digno.
Trabajo digno.
Pues esto sería un poco la idea de cómo funciona Material UI para que te vas haciendo la idea.
Lo chulo es que no tienes que importar ningún estilo.
Puedes meter estilos como en línea, como props.
Y más o menos va quedando bastante chulo.
Vamos a crear una página de inicio donde al hacer clic vamos a recuperar todas las preguntas.
Voy a crear aquí en public.
Me voy a copiar.
Le he pedido a ChasGPT que me haga un JSON.
Le he dicho, hazme un JSON con preguntas de JavaScript y me dice la respuesta.
Y me ha hecho todo esto.
Me ha hecho todo esto.
Pero te tengo que decir una cosa.
Se ha equivocado.
He estado viendo y ha dado un montón, un montón de errores, tío.
Ha metido un montón de errores.
Pero un montón.
He tenido que revisármelos todos porque todas las respuestas correctas, casi todas estaban mal.
Pero casi todos los correct answers estaban mal.
No entiendo.
O sea, mira que era fácil, ¿eh?
Pues nada, le ha cagado.
O sea, lo ha hecho más o menos bien, pero lo ha ido cagando.
Bueno, entonces, ahora que ya tenemos el data, yo lo voy a poner en el public porque le vamos a hacer un fetch de forma asíncrona.
Y así veremos cómo hacer estados asíncronos en Zustan y estados globales en Zustan.
Entonces, vamos a hacerle como una página de start.
No sé cómo llamarle.
Start.
Vamos a darle start.tsx.
Y esta va a ser la página que vamos a enseñarle al usuario para que le dé a empezar.
Esto lo vamos a hacer más que nada porque quiero tener...
Luego vamos a hacer un montón de cosas.
Vamos a persistir el estado global.
Vamos a poder resetearlo y todo esto.
Y entonces quiero que se pueda ver cuando estamos al principio.
Entonces, vamos a ponerle un botón de Material UI que cuando hagamos clic...
Bueno, por ahora vamos a dejarlo vacío.
Y ponemos la variante.
A ver, return.
Vale, variante.
Espérate, que aquí la he liado.
Ah, es que he hecho una mezcla aquí entre function y const que me he quedado a gusto.
Vale, vamos a utilizar la variante de content.
Esto está muy chulo porque obviamente tienes autocomplete.
¿Ok?
Aquí le vamos a poner que vamos a poner aquí empezar y cerramos el botón.
Y esto ahora lo arreglamos.
¿Vale?
Esto, el onclick este, luego lo arreglamos.
Vamos a...
Es que claro, se me va a quejar por cualquier cosa que ponga.
Se me va a quejar.
Pero bueno, lo dejo vacío.
No pasa nada.
Supongo que ahora mismo no se quejará.
Y este start, pues por ahora lo vamos a poner aquí.
¿Vale?
Start.
Lo ponemos aquí.
¿Vale?
Ya tenemos aquí nuestro botón de empezar.
Para empezar con nuestro start y todo esto, vamos a necesitar tener un estado.
¿Por qué?
Quiero que cuando le demos a empezar, haga un fetching de datos a una API, me recupere todas las preguntas y me ponga solo las que necesitamos.
Y además que me haga un random y todo esto.
Que esto lo vimos ayer justamente en un montón de proyectos.
Súper sencillo.
Vamos a empezar con Zustan y nuestro estado global.
Vamos a instalar Zustan como una dependencia exacta.
¿Ok?
Esto es para tener la versión exacta.
No sé por qué ha petado.
Si no he hecho nada.
Ha fallado algo import analysis.
Esto debe ser algo interno de bit que ha petado.
No tiene sentido.
Fijaos.
Yo aquí podríamos crear una carpeta que se llama store.
Que es un concepto muy similar al que tendría, por ejemplo, Redux.
El store sería como el sitio donde guardamos nuestro estado global.
Y podríamos tener un montón de stores.
En este caso, vamos a empezar con una y le vamos a llamar questions.
Questions.ts.
Aquí vamos a crear nuestro primer estado global con Zustan.
Así que utilizamos el create de Zustan.
Vamos a crear un types por aquí.
Types.d.ts.
Y vamos a crear...
A ver, ¿qué types podemos tener?
Vamos a ponerle las preguntas.
Al menos solo es uno muy fácil.
O sea, solo vamos a utilizar este.
Yo creo que solo vamos a tipar esto.
Que es tener la pregunta tipada.
Las preguntas, que podéis sacarlo de aquí, ¿eh?
¿Veis que tenemos aquí este JSON?
Esto al final le puedes pedir a chatGPT que te lo tipe.
Esto le dices a chatGPT, oye, típamelo.
Típame con TypeScript esto, ¿vale?
Y ya verás.
¿Cómo?
Me está respondiendo la pregunta.
Eres un poco tonto, ¿eh?
Es un poco tonto, tío.
O sea, no es lo que esperaba de ti.
Dame los tipos de TypeScript de este objeto.
Vale, a ver, ahora sí.
Ahora ha sido bastante más claro.
También ha sido culpa mía, ¿eh?
Bueno, pues ya tendríamos los tipos.
Súper fácil, rápido y tal.
Bueno, no me gusta lo de interface pregunta, que es un poco raro.
Pero ya tendríamos esto, que cada pregunta sería así, ¿vale?
El otro día alguien me dijo,
¿no está mal utilizar chatGPT para programar y tal?
Y yo la verdad es que no veo que sea algo malo.
No es malo que utilices chatGPT mientras programas.
Por ejemplo, ahora lo hemos utilizado.
¿Y qué problema hay?
O sea, si al final lo que nos ha hecho es acelerarnos.
Y al final no es interesante tanto esa parte para el curso de hoy,
pues qué más da.
O sea, que no sé.
Lo que está mal es perder el tiempo.
Muy bien, Geterabanco.
Muy buena, ¿eh?
Que no piensas.
Pero si es que esto ya lo sé.
Es verdad, no pienso.
Pero es que esto ya me es indiferente.
Esto es obvio que lo sé hacer, ¿sabes?
Lo que pasa es que para mí no me aporta que yo lo haga nada, ¿sabes?
Bueno, aparte de tener esta información,
vamos a tener también el User Selected Answer.
O sea, la solución que ha seleccionado el usuario,
que vamos a ponerle este interrogante para decirle que puede ser undefined.
Porque hay veces que no ha seleccionado nada.
Y Is Correct User Answer.
También vamos a poner que sea un boleano.
Y también vamos a poner que puede ser undefined,
porque a lo mejor no sabemos todavía.
Y esto es lo que vamos a utilizar para hacer el estado global.
O sea, que aquí cuando importemos, vamos a importar también el question, ¿vale?
De los tipos.
Importamos como type el question.
Y ahora vamos a tener una interface para nuestro estado.
Esto es interesante porque vas a ver que tipar el estado es súper fácil.
Vamos a tener questions, que va a ser un array de questions.
Esto, perfecto.
Vamos a ver en qué pregunta está el usuario.
Porque, por ejemplo, aquí, ¿ves?
Aquí está la pregunta 2 de 10.
Pero puede ir cambiando hacia adelante, hacia atrás.
Así que vamos a poner current question.
Y esto va a ser un number.
Y también vamos a tener un método o fetch.
Vamos a llamarle fetch questions.
No me gusta utilizar fetch, pero bueno, vamos a poner fetch.
Y le vamos a poner limit number.
Y esto devuelve void.
No devuelve las preguntas, porque lo que vamos a hacer es cambiar el estado.
Entonces, ¿para qué es esta interfaz que hemos creado aquí?
Esto lo que está haciendo es como explicar o describir cómo es el estado.
Y en el estado vamos a tener una propiedad que sea questions, un número que escurre en questions, y un método que es fetch questions.
Y ahora creamos el estado.
Esto también lo tendrías que hacer en Redux.
O sea, no creáis que esto es culpa de Zustan.
Vamos a exportar ya nuestro useQuestionsStore.
Y tan fácil como esto decimos, vale, vamos a crearla.
El tipo que vamos a crear es de state, que lo tenemos aquí arriba, es el justo el que hemos creado.
Y ya aquí tendríamos que indicar cómo creamos esto, ¿vale?
Esta parte de aquí que tenemos aquí, ya decimos, vale, pues esto va a tener un set.
Y esto directamente, esto lo he puesto mal.
Esto fíjate, a ver, os lo voy a poner primero mal, porque si no la gente se me va a volver loca.
Esto sería así. El create tiene que recibir un callback.
Y en el callback tienes que devolver el objeto que será el estado global, la store.
Donde vas a tener no solo el estado, sino las formas de actualizar el estado, ¿vale?
Por ejemplo, como ya hemos dicho, vamos a tener el questions, que va a ser un array vacío.
El current questions, que para empezar va a ser el cero.
Y aquí tendríamos el método que hemos dicho aquí, fetchQuestions, que va a ser,
si va a ser asíncrono, tenemos que decir que esto devuelve una promesa.
Así que vamos a decir que es asíncrono.
Aquí tenemos limit, que esto es el number.
Y esto devuelve, ya veremos el que devuelve, ¿vale?
Ya veremos lo que devuelve.
Pero con esto ya estamos creando el estado global.
Solo con esto. No hemos tenido que crear ni reducers, ni actions, nada.
Ya está. Con esto ya lo tendríamos.
Ya seríamos capaces de leer este questions en cualquier sitio,
sin necesidad todavía de seguir con el fetch, que ahora lo haremos.
Pero solo con esto que hemos hecho, ya tendríamos el estado global.
Ya podríamos ir, por ejemplo, a nuestra app, ¿vale?
Aquí. Y podríamos tener aquí const questions, use questions store,
y del state sacar, del state sacar el questions.
Y ya está. Aquí tienen las cuestiones.
Si hacemos un console.log de esto,
ahora veremos que aquí tenemos un string vacío.
Hay un string vacío, una array vacío.
¿Vale? ¿Ves? Array cero.
Y este array cero es este de aquí.
Bueno, de hecho, con el console.ninja también se ve.
Pero ¿veis? Ya tengo aquí, ya estoy leyendo el estado.
Si yo aquí en el questions tuviese más cosas, yo qué sé.
Voy a poner hola, aunque esto no le va a gustar a TypeScript, ¿vale?
Pero ¿ves? Ya tendría aquí el hola.
Ya lo estoy leyendo.
O sea, ya solo con esto ya tenemos el estado global,
ya lo estamos leyendo y ya lo podríamos leer desde cualquier sitio.
¿Ok?
Con el fetch questions este, vamos a que cuando le hagamos el click aquí,
cuando le demos a empezar, vamos a llamar a este fetch questions.
Y lo que vamos a hacer es actualizar el estado para que tengamos al menos una pregunta.
Vamos a hacer una cosa.
Cuando llamemos a este fetch questions, vamos a hacer un set aquí
y le vamos a meter la primera pregunta a esta, para que nos hagamos una idea.
¿Cómo tenemos que actualizar?
Al set, que esto lo estamos recibiendo aquí, aquí tenemos dos parámetros.
Uno, el set, que sería para actualizar el estado.
Y otro, el get, que sería para leer el estado.
De esta forma podemos, dentro de este objeto,
dentro de este objeto, podemos tanto leer como actualizar el estado.
Así que para actualizar el estado, aquí este set recibe también una función
donde vamos a tener el state y luego lo que queremos actualizar.
Aquí puedes hacerlo de diferentes formas.
Yo lo que voy a hacer para que sea más...
Bueno, de hecho, es que se puede hacer de otras formas.
Yo siempre lo hago así con la función,
pero fíjate que también le puedes pasar directamente el estado.
Esto es como el set state.
O sea, le podríamos pasar aquí directamente la pregunta.
O sea, podemos decirle que questions, questions y pasarle directamente lo que queremos actualizar.
Yo lo que normalmente hago siempre es utilizar este porque estoy acostumbrado,
pero no es obligatorio.
Esto debería funcionar.
Lo que estamos diciendo es actualízame el estado global con este objeto questions
y este questions, que es el que vamos a tener aquí,
ahora va a ser un array que va a tener un elemento.
¿Vale?
Así que así lo puedes hacer sin ningún problema.
También lo puedes hacer con una función, lo puedes hacer con un montón de cosas.
Esto sería lo que tiene que hacer cuando le demos a este fetch questions.
¿Dónde tiene que ocurrir esto?
Aquí, cuando le demos al empezar.
Así que vamos a traernos el fetch questions con el use questions store,
el state, sacamos state punto.
Y fíjate que al tenerlo tipado, cuando pones el punto ya te dice todo lo que tiene,
que esto es una gloria.
No tienes que hacer nada más.
Con que hagas esto, ahora ya solo tienes que utilizar el fetch questions cuando es necesario.
Y aquí vamos a tener el handle click.
Handle click.
¿Vale?
Llamamos el fetch questions y este handle click es el que haremos cuando hacemos on click.
Esta regla tampoco me gusta mucho.
Esto es una regla del Inter que me dice que todas las promesas tienen que ser esperadas
y no tener promesas flotantes ahí.
Pero esto es un rollo porque si tú empiezas a hacer aquí que esto es await y esto es async,
entonces se quejará TypeScript de que esto está devolviendo una promesa.
Es un poco rollo.
Y la verdad es que si tienes en cuenta lo que estás haciendo, pues no tiene mucho sentido.
Así que lo vamos a desactivar para que no nos esté rayando todo el rato esta regla de aquí.
¿Vale?
Así que vamos a slint.
Quitamos esto.
Le ponemos el off y ya está.
Así que, vale, aquí nos dice que esperaba un argumento porque le había puesto el límite.
Vamos a poner 5 para pasarle el argumento y ya está.
Así que ahora, ¿ves este fetch questions?
Cuando hagamos clic a este botón, vamos a llamar al fetch questions.
Le voy a dar clic, clic.
Parece que no ha pasado nada, pero fíjate que si yo voy al componente app,
ahora aquí el console log de questions, primero había sido un array vacío,
pero cuando le he dado clic ya tenemos aquí el primer elemento.
O sea, ya hemos visto cómo funciona que realmente sí que se está actualizando.
Cuando le damos a empezar, se está actualizando el estado y aquí lo que está pasando
es que está cambiando el valor de questions.
De hecho, para que lo veas más claro, vamos a poner questions.length,
se iría a 0, ¿vale?
Si el questions.length es 0, hacemos esto.
Y si no, vamos a poner aquí, si es mayor a 0, vamos a poner juego, ¿vale?
Y ahora luego, ahora hacemos el componente de juego, ¿vale?
Le damos aquí, empezar, clic, juego.
¿Vale?
¿Veis que ha cambiado aquí?
O sea, que ya tenemos un estado global, amigos.
Ya tenemos un estado global.
Súper fácil.
Y total, en una línea sin configuración, ni siquiera tengo que hacer el provider,
no tengo que hacer absolutamente nada.
Entonces, ya tenemos el estado global, ¿vale?
Tenemos el estado global, lo estamos leyendo, lo estamos actualizando.
Pero, obviamente, no queremos hacer este setaje.
Esto no tiene mucho sentido.
Lo que vamos a hacer en este fetch questions es,
vamos a recuperar de una API,
podrías recuperar de una API de donde tú quieras,
pues hacer una wait, fetch,
decimos aquí, http, localhost 5173,
que es el puerto en el que está,
y hacemos un fetch del JSON, data.json, y ya está.
Pero imagina que esto es una API y le cambiáis la URL.
Puedes hacer lo que queráis ahí.
Await, rest.json, ¿vale?
Y ya tenemos aquí el JSON.
O sea, hacemos un console.log, veremos el JSON.
¿Vale?
¿Veis?
Aquí ya tenemos toda la data,
con todas las cuestiones.
Perfecto.
Pues, ahora que tenemos el JSON,
vamos a, como teníamos que limitar el número de preguntas,
vamos a hacer un JSON.sort.
No pasa nada que hagamos un sort,
porque este JSON se acaba de crear.
No pasa nada que lo mutemos, ¿vale?
Hacemos este truquito para que nos lo desordene,
y hacemos el slice para limitar el número de resultados
por el número que nos ha pasado de parámetro.
Y aquí en el questions, pues nada, ya está.
Ya tendríamos aquí set,
le decimos questions, y ya está.
Este questions que tenemos aquí, este de aquí,
es el que vamos a actualizar con esta información de aquí.
Punto pelota.
Ya está.
Así que ahora, cuando guardemos los cambios,
si hago aquí un empezar y le doy clic, ¿vale?
Pone aquí juego.
Si vamos aquí, ah, he quitado el console.log,
pero voy a poner el console.log para que lo veas.
Si ponemos aquí el console.log, ¿ves?
Aquí ya tenemos las cinco preguntas que están desordenadas,
obviamente, pero ya tenemos cinco preguntas para hacerle al usuario
de este JavaScript quiz, que queremos pedir diez,
las que sea, ¿vale?
Pues eso lo podemos cambiar aquí en una constante,
o en un punto enf, o lo que sea.
O limit questions, limit questions.
Vamos a poner diez, pero si queréis cinco,
veinte, lo que sea, esto también podríais tener
una configuración que fuese un estado global para cambiarlo.
Dejad volar vuestra imaginación, ¿vale?
Dejad volar vuestra imaginación.
Y ahí podréis hacer un montón de cosas.
Entonces, ahora que ya tenemos esta forma de limitar
y ya tenemos que empezaría el juego,
pues vamos a hacer el juego.
Así que vamos a crear aquí un game.tsx,
export const game,
y aquí empezamos a estilar nuestro juego.
Vamos a importar el icon button y el stack
del muy, muy, material, vale.
Y vamos a empezar a estilar un poco
cómo debería ser el juego
para que la gente pueda jugar y todo esto.
A ver, ¿podríamos hacer el navegador de páginas?
¿O qué hacemos primero?
Hacemos primero las preguntas, ¿no?
Que tiene un poquito más de sentido.
Hacer primero las preguntas.
Las preguntas.
Vale, vamos a hacer primero las preguntas.
Vamos a hacer un question por aquí.
Const question, ¿vale?
Que le vamos a pasar el info, ¿vale?
Y aquí vamos a poner question
y aquí le pasaríamos la info.
¿De dónde sacamos la información de la pregunta?
Podemos hacerlo un montón de formas, ¿no?
Pero si miramos el estado,
fíjate que mirando el estado,
sabemos cuál es la pregunta actual,
que es la cero,
porque al principio empezaremos por la cero.
Esto será la posición del array de questions, ¿no?
De este questions que tenemos aquí.
Podemos hacer un montón de cosas,
pero para que lo veamos claro,
lo primero que podríamos hacer aquí
es recuperar las questions.
Así que tenemos aquí esto
y podemos recuperar el current question.
¿Cuál es la pregunta actual
que tenemos que enseñarle al usuario?
Vamos a poner esto por aquí.
Vamos a comentar esto.
¿Vale?
Y aquí vamos a poder sacar el question info
de todas las cuestiones
y recuperando el current question.
Y este question info se lo pasamos aquí
y esta info que tendríamos aquí
sería simplemente el tipo question,
porque es lo que le va a llegar,
el question.
Canop views a JSX component.
Ah, porque...
Vamos a cambiarle esto.
As question type,
para que no entre en conflicto
con el nombre del componente.
¿Por qué sigue quejándose?
Porque si...
Ah, igual es porque todavía no estamos.
Vale, ya está.
Entonces, lo que estamos haciendo en el juego
es recuperar la pregunta
que le tenemos que enseñar al usuario.
Esto se lo estamos pasando
a otro componente llamado question.
Lo podríamos hacer directamente,
pero esto luego lo vamos a separar
porque quiero poner la navegación
hacia adelante y hacia atrás.
¿Vale?
Y ojo, porque aquí viene lo interesante
de todo el juego.
De todo el juego que queremos hacer,
aquí está todo lo interesante.
¿Qué tiene cada pregunta?
Las preguntas tienen la pregunta,
el código y las opciones.
Así que vamos a mostrar paso a paso
cada una de estas cosas.
¿Vale?
Vamos a crear aquí una...
Vamos a utilizar la card
con...
A ver qué variantes hay.
La...
Mira, outline.
¿Vale?
Ponemos aquí a la card.
Vamos a crearlo todo en una card
como si fuese como este
que tiene aquí como una card.
Vamos a intentar hacer algo similar.
Tampoco vamos a hacer
el mejor estilo del mundo.
Luego se pueden aburrir
y pueden hacer lo que quieran.
Entonces, vamos a poner aquí
lo primero, la pregunta.
¿Vale?
Así que typography, variant, h5
y ponemos aquí info.question.
Aquí debería tener info.
Ahora.
Vale, que no salía...
No estaba saliendo el autocomplete.
¿Vale?
Vale.
Y este game vamos a renderizarlo
en nuestra aplicación.
¿Vale?
Porque ahora estamos renderizando
esto de juego.
No tiene sentido.
Vamos a renderizar el componente game.
¿Vale?
Vale.
¿Cuál es la salida de este código?
O sea, que ya tenemos la pregunta.
Ya estamos enseñando la pregunta.
Game.
Vamos a seguir con el siguiente paso.
Lo siguiente debería ser
enseñar el código.
Vamos a enseñar el código
de una forma tan sencilla
que te va a volar la cabeza.
Vamos a utilizar
React Syntax Highlighter
que no sé si lo conoces.
Es este componente de aquí.
Hay un montón de componentes
para hacer syntax highlighting.
Pero yo voy a utilizar este
porque me lo conozco
y porque sé que es bastante fácil
de hacerlo en un momento.
Y además que tiene un montón de temas
que está uno de mis favoritos
que es el OneDark.
Gradient Dark.
¡Uh!
Este es súper bonito.
Gradient Dark.
Este me ha encantado.
Este me ha encantado.
Bueno.
Pues vamos a utilizar
el React Syntax Highlighter.
¿Vale?
Este es un componente
con el que puedes hacer
que se vea el código
como si fuese un editor
súper bonito y tal.
Así que vamos a instalarlo.
Para eso nos copiamos
este nombre de aquí.
¿Vale?
Y aquí hacemos un pnp install.
Así.
Versión exacta.
Esto es para que no me ponga
el caret.
¿Vale?
La cosa esta.
¿Ves aquí?
Esto es el caret.
Entonces si le pones el menos C
no te lo pone.
¿Por qué?
Porque yo no lo uso.
Y ahora que ya tenemos
este paquete instalado
pues nada.
Lo importamos aquí.
Vamos a importar aquí
syntax highlighter.
No sé si lo he escrito bien.
React Syntax Highlighter.
Lighter.
Vale.
Creo que sí lo he escrito bien.
Este sería el componente
para hacer syntax highlighting.
Y luego vamos a importar también
pues no sé cómo sería el
React Syntax Highlighter
barra this barra sm
barra styles
barra hljs.
Y entre todos los estilos
vaya.
No tiene autocomplete.
Pensaba que tendría autocomplete.
No sé cómo se...
El gradient este.
Vamos a ver si...
Sí sale aquí.
Select.
El gradient.
Yo imagino...
Ah, pues no.
Bueno, me imagino que sea camel case.
Vamos a probarlo.
Me imagino que esto sea
gradient dark.
Si esto lo he puesto bien.
A ver.
Vamos a poner esto.
Dist barra...
No.
Sm no me sale.
Sm.
Yo creo que es así.
Styles.
Yo creo que es así.
Ah, lo veremos.
Vale.
Fijaos que se me queja aquí en rojo
una cosita que me dice
oye, no puedo encontrar la declaración
no sé qué.
Y ya te dice aquí...
Esto es un error de TypeScript
porque este paquete
no tiene tipos.
Esto para que no nos dé errores
y esté ahí en rojo
y moleste y tal
pues lo que vamos a hacer
es poner esto.
Vamos a instalar
los tipos
para que no nos molesten.
Lo ponemos en modo desarrollo
porque no es necesario
en producción
y esto va a instalar
los tipos de este paquete
porque este paquete
no los trae por defecto.
Bueno, pero ved
que ahora ya no da ese problema
sino que da el problema
de que no lo estamos usando.
¿Vale?
Así que ahora vamos a usarlo.
Simplemente ponemos aquí
le decimos
Sinta Highlighter
le decimos
en qué lenguaje
es el que queremos
que se vea
en este caso
por Language
JavaScript
y aquí en Style
le pasamos el estilo
que sería el gradient dark
que tengo que mirar
si en realidad
es gradient dark
claro, lo veremos.
Ahora lo deberíamos ver.
Vamos a ver
aquí en nuestra aplicación
empezar
¡Ojo!
Vale, me lo está centrando todo
cosa que no queremos
que nos haga
así que vamos a poner aquí
un text align
left
que yo creo que esto
también es así.
Ah, pues el card
no acepta esto.
Bueno, se puede utilizar
esto
SX
que sería para los estilos.
¿Vale?
Y así ya los tenemos así.
¿Qué más podríamos ponerle?
Vamos a ponerle
otro color a esto
que queda un poco raro.
Vamos a ponerle este.
¿Vale?
Y vamos a ponerle
un padding también.
Puedes utilizar padding
o puedes utilizar la P
que es como una forma
corta de hacerlo.
Y así
pues ya teníamos esto.
Oye, ¿ves qué color?
Porque esto
ah, porque es todo en minúscula.
Vale, todo en minúscula.
O background color
lo que queráis.
¿Vale?
Y vamos a poner
que el color
ah, se me ha olvidado
una cosa.
¿Veis que este texto
me lo ha puesto en negro?
Vamos a hacer una cosa
amigos
el dark mode
de material UI.
Tenemos que hacer esto.
¿Vale?
Para que se vea bien
material UI en dark mode
porque veis que se ve mal
a ver, podría empezar
a estilarlo todo
en blanco
no sé qué
pero es que sería un poco
sería un poco raro.
Así que lo que vamos a hacer
es
añadir esto
que es un momento
lo que tenemos que hacer
en el punto de entrada
de nuestra aplicación
aquí
tenemos que importar
estas dos líneas
de código de aquí
así que las importamos
¿Vale?
Y tenemos que crear
el dark theme
donde decimos
cuál es la paleta
que queremos utilizar
¿Veis?
La paleta
el modo dark
y este dark theme
lo que hacemos es
un provider
de toda nuestra aplicación
¿Ok?
Esto por aquí
envolvemos toda nuestra aplicación
con este theme provider
y también
tenemos que poner
CSS baseline
aquí
y ahora con esto
sí que deberíamos
tener el modo oscuro
correctamente
¿Vale?
Ahora sí
¿Vale?
Ahora sí
Ah, he puesto javascript
javascript
es esto lo que decíais
¿Vale?
Ahora sí
ahora sí que sale bien
¿Vale?
Lo que nos falta ahora
es la lista
¿Vale?
Tenemos la pregunta
el código
nos falta esta lista
la lista
la vamos a tener aquí pegada
y oh sorpresa
se llama lista
para hacer una lista
se llama lista
vamos a ponerle ya
un colorcito
que sea así como gris
y al poner la lista
aquí es donde vamos a estar
iterando todas las respuestas
posibles para mostrárselas
al usuario
utilizamos el last list item
y aquí
tenemos que ponerle aquí
aquí no pasa nada
que utilicemos el index
porque la respuesta
no van a
no van a cambiar de orden
ni van a desaparecer
ni va a pasar nada
¿Vale?
pero si fuese el caso
no utilicéis el index
o podríamos utilizar una idea
en el data
crearle una idea
a cada una
en este caso
no pasa nada
que utilicemos el index
¿Vale?
pero es importante
que sepáis
cuando se puede
y cuando no se puede
list item
list item
button
vamos a añadir
para cada elemento
un botón
y en este botón
vamos a poner
finalmente
list item
text
¿Vale?
el texto
y el texto primario
va a ser
la respuesta
de cada una
de las que estamos haciendo
vamos a ver si
esto renderiza
list item
text
vamos a ver si esto
renderiza de todas
¿Vale?
este sí
este aquí
esto cierra aquí
esto aquí
esto aquí
esto aquí
y ya terminamos
¿Vale?
ya tenemos aquí las opciones
al menos salen las opciones
aunque veis que tiene
como un padding raro
esto es un tema
de material UI
puedes ponerle
disable padding
que esto empieza
entonces a mejorar
ves ahora le ha quitado
algún padding
aquí también creo que
también teníamos que poner
el disable padding
¿Vale?
ahora sí que queda esto
alineado
¿Vale?
y aparte de esto
porque este
el VG color
ah porque se lo he puesto
otra vez todo mayúscula
la madre que me parió
¿Vale?
vale
al menos así
tenemos un poco
las opciones
que se vean
un poco más clicables
y ya está
le estamos mostrando
al usuario
las opciones
o sea
fijaos que estamos haciendo
podríamos centrar
las opciones
si queréis
las podéis centrar
text align
center
si os gusta centradas
pues las centramos
no sé
lo tenemos que hacer aquí
no sé
lo tenemos que hacer aquí
text align
ah no sé
cómo la podríamos centrar
la verdad
porque
cuando uno utiliza
componentes
mira ahora
ya está
para que se parezca
un poco más
podríamos poner
que cada una
no sé si habrá
alguna forma
de poner un borde
guter
creo que
que se podía
¿Vale?
vamos a poner
border
podríamos hacer
que todas
estuviesen en un borde
claro
pero si todas
tienen un borde
se va a ver mal
claro
es que lo tienen
por los lados
es un poco raro
la verdad
lo que sí que tienes
abajo ¿no?
claro
lo tiene abajo
y ya está
es mejor tenerlo
activo
ah
dividers
dividers
es verdad
material UI
tiene esto
del divider
esto de aquí
que
¿cómo lo podemos?
vale
se lo tenemos que poner
a cada uno
y entonces ya aparece así
directamente
no me gusta nada
esto por defecto
que tiene que
veis que deja ahí un espacio
no me gusta nada
vale
pues a cada uno
se lo ponemos el divider
y ya está
y entonces así
ahora lo tiene dividido
le podríamos poner la negrita
bueno
ahí no tiene negrita
pero bueno
se lo vamos a poner
por si
volt
pues esto
tampoco va aquí
vamos a quitar este de aquí
y se lo vamos a poner aquí
y ya tendríamos al menos
bueno
si no volt
que a lo mejor volt es muy exagerado
vamos a poner 500
ah
pues tampoco
o sea no
no tiene volt
bueno
no se puede hacer volt
es que no sé dónde
diría el volt
pero en algún sitio
diría el volt
bueno
da igual
el volt tampoco era importante
sigamos
que está interesante la cosa
ya eso nos queda
ahora cada vez que el usuario
pues pregunte
o diga cualquier cosa
bueno ahora le añado
un poco de separación
a esto
vale
vamos a poner aquí
mt
no
margin
top
vamos a ponerle
4 por ejemplo
vale
para que esté un poco más separado
ahora que ya tenemos esto
ahora está lo divertido
amigos
ahora está lo divertido
porque tenemos que
que el usuario
pueda seleccionar la pregunta
o sea ahora tendríamos que permitir
que el usuario
pueda seleccionar la pregunta
y como hacemos esto
como hacemos que el usuario
diga vale
cuando le he dado click
me he quedado con esa pregunta
vamos a tener que hacer otra vez
un store
vamos a hacer una store
en la que
si nos fijamos
en la store
ya teníamos en el estado
teníamos que cada pregunta
las questions
si miramos la interfaz
de las questions
teníamos
user selected answer
o sea ya teníamos una forma
en la que se podía seleccionar
cual era la solución
que ha dicho el usuario
pues en questions
vamos a añadir
un método más
que le vamos a llamar
select
select answer
vale
donde le vamos a pasar
el question id
no sé si pasarle el id
o el
bueno si el question id
que es más fácil
que es un número
y vamos a pasarle
el answer index
que también será un número
aquí lo que le vamos a decir es
oye
de esta idea
de esta pregunta con esta idea
me tienes que marcar
esta pregunta
con
o sea esta solución
con esta
con este índice
y esto va a devolver
esto no debería ser asíncrono
o sea que esto debería devolver un void
y ya está
vale
esto es lo que vamos a hacer
vamos a tener una nueva forma
de que el usuario
cuando haga click
ah mira esto está
este está mal
es que hay algunos que me los generó mal
vale
que cuando haga click
nos cambie esto
así que
vamos a poner esto por aquí
y ahora aquí
vamos a poner
el selecancer
ok
vamos a ver que tenemos que hacer aquí
ojo
madre mía eh
hostia
pues que me lo ha hecho ya entero esto
me lo ha hecho entero
a ver
lo podríamos hacer así
yo
porque quiero que
aprendáis el structure clone
lo vamos a hacer con structure clone
pero lo podríamos hacer
como ha hecho
el hackopilot
nosotros vamos a usar
el structure clone
sirve para clonar objetos
de forma
profunda
así que podríamos tener aquí
un new questions
structure clone
de las questions
y aquí está la pregunta del millón
¿no?
¿de dónde sacas las questions?
imagínate que lo quieres hacer así
¿cómo podrías
desde este método
poder acceder
a esta propiedad
del estado global?
¿cómo puedes leerlo aquí?
pues lo que puedes hacer
es llamar al método
get
este que teníamos aquí
este get
lo que te devuelve
es el estado
y puedes llamarlo así
directamente
y ya lo tendrías
o puedes acceder
solo a la parte
que te interesa
por ejemplo
podríamos sacar
questions
porque este get
te devuelve
este objeto
que tenemos aquí
con el estado
el valor que tenga
¿vale?
así que es súper interesante
porque así ya
estamos recuperando
el valor del estado
para poder actualizarlo
aquí voy a
lo que voy a hacer
con el structure clone
es que voy a clonar
voy a clonar directamente
todas las preguntas
y solo voy a cambiar
aquella que necesito
en concreto
así que de todas
estas preguntas
vale
lo que voy a hacer
primero es buscar
vamos a ver
el question index
lo vamos a encontrar
vamos a tener
que buscar
el índice
del id
de la pregunta
porque veis que tenemos
las id
claro
como tenemos las id
no tenemos el índice
porque lo hemos desordenado
y todo
pues lo que vamos a hacer
es utilizar
new questions
punto
find index
y utilizando la id
que le estamos pasando
por parámetro
le vamos a decir
oye
encuéntrame
la pregunta
que la id
sea igual
al question id
¿vale?
esto no hace falta
que no sé por qué
esto lo ha hecho así
pero aquí tendríamos
el question index
¿vale?
primero sacamos
encontramos
el índice
de esa pregunta
una vez que tenemos
el índice
vamos a recuperar
la información
así que
de new questions
sacamos el question index
y ya está
la verdad
claro
el question index
lo vamos a necesitar después
¿por qué no hago el find?
porque el question index
lo vamos a necesitar después
para actualizarlo
entonces
así
no solo me sirve
para recuperar la información
sino que también
para actualizarla después
porque si yo hago el find
sí
recupero el objeto
con la información
pero luego
cuando la quiera actualizar
tendría que volver a hacer un find
o tendría que volver a encontrarlo
entonces
voy a mirar
cuál es el índice
de la pregunta
que está dándole click
el usuario
voy a recuperar la información
y luego la voy a actualizar
utilizando este índice
¿vale?
ahora
vamos a ver
el usuario
ha hecho bien
ha hecho bien la pregunta
cuando ha hecho click
ha seleccionado la correcta
pues es muy simple
vamos a mirar
is correct
user answer
si la pregunta
la pregunta
que tenemos aquí en data
ves que tenemos aquí
correct answer
es la 3
y esto sería 0
1
2
y 3
o sea
la correcta sería esta
vamos a ver
a qué índice
le ha dado el usuario
si la respuesta correcta
es igual
al answer index
significa
que es la respuesta correcta
y así tendríamos
un boleano ya
sabiendo si el usuario
ha hecho la respuesta correcta
y ahora solo
necesitamos actualizar
el estado
y para actualizar el estado
lo que podemos hacer es
primero
mutamos la copia
que hemos hecho
¿vale?
voy a ir poniendo
encontramos
la
el índice
el índice
de la pregunta
lo voy a dejar
con comentarios
por si alguien
luego lo hace
obtenemos
la información
de la pregunta
averiguamos
si el usuario
ha
seleccionado la respuesta
correcta
y ahora actualizamos
el estado
para actualizar el estado
primero
vamos a
cambiar
esta información
en la copia
de la pregunta
y esto significa
que ahora sí
accedemos a
new questions
question index
y esto va a ser
el objeto
con todo el
selected question
¿no?
la
iselected question
o question info
con toda la información
que tenía
la pregunta
y además
vamos a añadirle
si es correcta
la pregunta
del usuario
y el selected
user selected answer
que es
el answer index
¿vale?
que nos va a servir
para indicarle
visualmente
si es esa
la que ha seleccionado
si estaba bien
y todo esto
y todo esto
ahora sí
actualizamos
el estado
y para actualizar
el estado
hacemos un set
de questions
new questions
y así ya tendríamos
la actualización
del estado
cuando seleccionamos
una pregunta
vamos a utilizar
el select answers
¿vale?
cuando le dé el click
el usuario
que se vaya seleccionando
la respuesta correcta
¿vale?
y así veremos
diferentes cosas
que están bastante
interesantes
para que visualmente
veamos
qué es lo que está
haciendo el usuario
vamos a question
al game
¿vale?
en el game
teníamos aquí
todos los botones
estos que tenemos aquí
que al hacer click
pues ahora mismo
no pasa nada
lo que vamos a sacar aquí
es el select answer
vamos a sacar
cuál es la información
cuál es la
vamos a sacar
el select answer
que es la acción
que acabamos de hacer
esto que hemos hecho
¿no?
para que el usuario
pueda seleccionar
cada una de las respuestas
así que
state
state
punto
select answer
¿vale?
y aquí vamos a crear
un handle click
donde le vamos a pasar
y esto
esto le vuela la cabeza
a la gente
muchas veces
el index
el answer
más que index
vamos a poner
answer index
¿vale?
que es el número
y esto
lo vamos a hacer así
y aquí ya podemos llamar
select answer
donde le vamos a pasar
de la información
de la pregunta
la idea
y el índice
de la respuesta
y ahora te explico esto
que esto
mucha gente
le vuela la cabeza
de una función
que devuelve una función
pero es que esto es
esto es
del día a día ya
esto lo vamos a poner
el botón
el on click
aquí
y aquí
utilizamos un
create handle click
que le pasamos
el índice
¿ok?
y con esto
ya tendríamos
al menos el seleccionar
cada una de las respuestas
¿qué significa
este create handle click?
lo que estamos haciendo aquí
es crear
una función
que lo que va a hacer
a su vez
es devolver
una función
que va a ser
el handle click
o sea
esta función
devuelve
una función
que es
la del handle click
¿vale?
¿por qué?
porque si no
tendríamos que
podríamos hacerlo
de diferentes formas
o sea
realmente
otra forma
que podríamos hacer esto
lo que tú quieras
podrías
quitarte esto
podríamos evitar esto
y entonces aquí
pues este
es todo esto
todo esto
hacerlo aquí
lo podrías hacer aquí
¿vale?
podrías tener aquí
esto
¿no?
y tener aquí esto
por ejemplo
a ver
no pasaría nada
que lo hicieses así
a mí
personalmente
no me gusta
muchas veces
bueno
no es tanto
por closures
pero es más
por cómo funcionan
las funciones
esto es básico
de cómo funcionan
las funciones
en javascript
porque son
las funciones
se pueden tratar
como cualquier
tipo de variable
y por lo tanto
puedes enviarlas
como parámetro
puedes hacer lo que tú quieras
para tener la información
del index
puedes hacerlo así
directamente
y crear aquí
la función
pero claro
esto es un poco rollo
porque si esta función
fuese mucho más grande
sería un poco raro
¿qué es lo que puedes hacer?
sacar esto de aquí
y esta función
la creación de esta función
la estamos haciendo aquí
fíjate
que esta parte de aquí
esta parte de aquí
si tú la borras
y pego
lo que acabo de quitar
lo tenemos igual
solo que este index
se lo tenemos que pasar
como parámetro
pero no se lo puedo pasar
por aquí
porque esto
es el handle click
esto es
la función
que va a estar respondiendo
al click
y aquí no tenemos
esa información
aquí lo que le llega
es el event
del target
de esta forma
lo que estamos haciendo
es decir
voy a crear una función
es una función
que genera funciones
entonces estamos creando
una función
a través de un parámetro
le decimos
vale
voy a crear
el handle click
a través de este parámetro
de aquí
ya está
así que hacemos
el answer index
aquí
esto
pasamos por aquí
y así este
create handle index
ahí
create handle click
le puedes pasar el index
y esto
se cambiará
por esto de aquí
y ya está
ya tenemos lo del click
esto estará bien
porque vale
habremos recuperado
estaremos indicando
la pregunta
pero ahora el tema es
claro
si tenemos la pregunta
pero visualmente
no estamos viendo
cuál es la pregunta
correcta
que tiene el usuario
cuál es la que le gusta
la que no le gusta
todo esto
¿sabes?
o sea
cuál es la que ha elegido
el usuario
eso no lo vamos a ver
vamos a hacer una cosa
en el game
¿veis que le pasamos
la información?
esta información
llega de aquí
del questions
y este questions
cada vez que nosotros
estamos cambiando
una respuesta
vamos a ver aquí
un console log
¿ves?
vamos a ver questions
y cada vez que yo le dé click
¿vale?
ves
por 2
por 3
por 4
¿por qué pasa esto?
porque obviamente
lo que está ocurriendo aquí
es que cada vez que el usuario
está cambiando el estado
se está volviendo a renderizar
este componente
y fíjate
por ejemplo
id2
y ya me está diciendo
es correcta
true
¿cuál es la que ha seleccionado
el usuario?
la 2
¿vale?
o sea que he seleccionado
esta de aquí
la de 57
y según esto
es correcto
¿vale?
o sea que esa información
ya la tengo
y ya la está recibiendo
este question
así que aquí
lo que vamos a hacer
es magia
vamos a crear
un método
que se llama
get background color
para poder enseñar
al usuario
si su respuesta
ha sido correcta
o no ha sido correcta
así que de la información
de la pregunta
este info
que tenemos aquí
que es la información
de la pregunta
podemos sacar
dos cosas
y esto lo podemos ver
aquí en el tipo
podemos sacar
el user selected answer
y el is correct
user answer
podemos sacar
si es la respuesta
correcta
y cuál es la que ha seleccionado
el usuario
aparte de la respuesta correcta
que también es bastante útil
la verdad
así que esto igual
también lo podríamos sacar
vamos a sacar
el user selected answer
y esto de info
¿vale?
y también vamos a sacar
el correct answer
bueno
la verdad es que estoy pensando
bueno
podríamos
bueno
sí
con esto
con estas dos
la que ha seleccionado
el usuario
y la respuesta correcta
yo creo que con esto
ya lo podemos hacer todo
¿por qué?
porque podemos decirle
voy a poner que esto sea transparent
por ahora
y este get background color
lo vamos a llamar
para el botón
¿vale?
¿veis este botón
que tenemos aquí?
pues este botón
le vamos a poner unos estilos
sx
background color
¿vale?
background color
get background color
que le vamos a pasar el índice
y gracias al índice
vamos a poder saber
si esta pregunta
la tiene chequeada al usuario
si es la correcta
si es la incorrecta
vamos a hacer algo parecido
a lo que hacen aquí
¿vale?
fijaos que cuando entráis aquí
y os pregunta
si tú le das a
bueno es que esta no tiene mucho sentido
sí
joder
esta tampoco tiene sentido
es que quiero ser una de cuatro
¿vale?
cuando tú le das a una
te dice que está bien
las otras las pone con opacidad tal
pero además
si la pones mal
¿vale?
si la pones mal
te indica la que has puesto mal
y te dice cuál es la buena
pues todo esto lo vamos a hacer
con un método
la función de
get background color
¿no sería una buena práctica
reciba el info como dependencia?
puede ser
se podría hacer
a ver
yo en este caso
muchas veces
este tipo de funciones
que están dentro de componentes
que ya funcionan
dentro del componente
se podría sacar
o sea esto lo podríamos sacar
del componente
y entonces podríamos hacer
lo que dices
podríamos sacar de aquí
¿vale?
y entonces
aparte del índice
pasarle la info
y esto sería la question
y tal
si lo quieres hacer así
pues no me
ah
tomalo de esto
info
info
question
index
number
¿vale?
si lo quieres hacer así
pues está
está bien
no hay ningún problema
y entonces pues
aquí ahora
obviamente
tenemos que pasarle la info
y el index
¿vale?
y la sacas fuera del componente
porque si la dejas dentro
tampoco tiene mucho
¿sabes?
no tiene mucha historia
pero si la sacas fuera
bueno pues entonces
sí que tiene
tiene un poquito más de gracia
¿vale?
aquí dice que info
is not defined
pero eso ahora se arreglará
seguramente
pues vamos a intentar hacer esto
para hacer esto
ya el estilo del background
se lo vamos a poner aquí
en cada uno de los botones
pero
a cada botón
tendremos que ver
si hay que
si hay que añadirle esto
por ejemplo
primero
si el usuario
usuario
usuario
no ha seleccionado
nada todavía
pues eso significa
que el user selected answer
tiene que ser diferente a null
y entonces aquí
lo que hacemos es
devolver transparent
¿vale?
no la liamos
lo dejamos transparente
lo dejamos exactamente igual
¿vale?
si ya seleccionó
pero la solución
es incorrecta
¿vale?
si la solución es incorrecta
esto significa
que el index
que ha
o sea
la que estamos mirando
es diferente
al corre cancer
¿vale?
y además
el index
es diferente
a la que ha seleccionado
el usuario
y en este caso
también sería transparente
yo o sea
ahora mismo
lo estamos haciendo
esto se podría mejorar
los casos
pero yo ahora mismo
lo estoy haciendo
como caso por caso
para asegurarnos
que lo estamos haciendo todos
¿vale?
si esta es la solución
correcta
si es la solución
correcta
independientemente
que el usuario
la ha clicado o no
aquí ya vemos
que se pone en verde
por lo tanto
si es la solución
correcta
si el index
es igual
el index
o sea
la que estamos mirando
el botón
que estamos mirando
ahora
es la solución
correcta
entonces
bueno
uno a uno
no sé qué es
pero le voy a poner green
para ver si
a ver cómo sale
si esta
es la selección
del usuario
pero no es correcta
esto significa
que el index
es igual
a user selected answer
¿no?
y aquí le ponemos rojo
¿vale?
ahora veremos
si quedan bien los colores
y tal
y por ahora
vamos a poner
si no es ninguna
de las anteriores
ok
vamos a ver
ah mira
ya se ha puesto en verde
se ha puesto en verde
esta
o sea que
bien
a ver si le damos aquí
vale
¿qué pasa?
que se pone en roja
se pone en rojo
y se pone en verde
la buena
o sea tú le vas dando
y ya se pone en rojo
la mala
y la buena
se pone en verde
obviamente
no deberíamos dejar
que siga clicando
así que vamos a arreglar esto
para que el usuario
pueda seguir clicando
¿qué podemos hacer aquí?
pues nada
simplemente desactivar
desactivar
o sea vamos a decirle
vamos a poner un disable
de si el info
user selected answer
es diferente a nul
¿no?
o sea si
vamos a desactivar el botón
¿ves?
ahora ya lo hemos desactivado
vamos a volver a refrescar
empezar
ahora podemos seleccionar
3
¿vale?
y vemos
que esa está en rojo
y aquí que tenemos el 11
y que lo tenemos ahí
con el colorcillo
¿vale?
o sea que ya tenemos
la selección del usuario
en un momentito
el confeti
venga vamos a hacer confeti
de hecho el confeti
lo podéis hacer en dos sitios
lo podríais hacer aquí
si queréis
o lo podríais incluso hacer
para que veáis
como de potente es esto
el tema de
de Zustan
podríais hacerlo aquí
en un momento
o sea podríais
canvas confeti
¿vale?
importamos aquí
import confeti
from canvas confeti
y este confeti
a ver
sería un poco polémico
pero poder se podría hacer
se podría hacer esto
y podéis tener aquí
como un side effect
total
cuando total
al final
esto tampoco pasaría nada
en este caso
y a ver
vale
ahora la hemos puesto mal
a ver la voy a leer
la voy a leer antes de ejecutarla
¿cuál es el resultado siguiente?
1, 2, 3
vale es esta
ya está
ya tenemos el confeti
también lo podéis hacer
cuando acabe la prueba
lo podéis hacer cuando queráis
o sea os dejo a vosotros
que cambiéis el celdo del confeti
para hacerlo aquí
hacerlo al final
hacerlo cuando queráis
¿vale?
perdón
¿por qué va fuera
el get background?
va fuera
porque me ha dado la gana
o sea va fuera
porque he querido
no por otra cosa
¿vale?
no
la puedes dejar dentro
pero si lo dejas dentro
tienes que
básicamente
cambiar la forma
en cómo está hecha
la puedes dejar dentro
si quieres
lo que pasa
si la dejas dentro
piensa que es una función
que se va a estar creando
en cada renderizado
al dejarlo fuera
esta es una función
función
que se crea
una vez
si la dejas dentro
si tienes 80
componentes
question
pues se renderizará
80 veces
ya está
es la única diferencia
y la forma de inyectarle
la información
pues ya está
lo bueno de esto
que es mucho más fácil
de hacerle testing
porque le inyectas
la información
y aquí puedes testear
mucho más fácil
que tenerla dentro
de un componente
y te evitas el tener
que utilizar el use callback
para tener que mejorar
esto
vamos a hacer una cosa
porque fijaos
que aquí tiene
el anterior
el siguiente
y esto
eso lo podemos hacer
nada
lo vamos a hacer
en un momentito
y creo que va a hacer
que quede bastante bien
porque cada vez
que el usuario
pues conteste una
va a poder seguir
porque así
vamos a poder ver
más preguntas
ver cuántas nos quedan
y todo esto
así que aquí en el game
aquí que teníamos esto
vamos a necesitar
crear dos funciones más
de nuestra store
para poder movernos
porque fíjate
que ahora el current question
siempre es cero
nunca vamos hacia adelante
o hacia atrás
pues ahora necesitamos aquí
un go next question
¿vale?
y esto
debería ser un set
bueno
questions
claro
esto está muy bien
muy bien pensado
Gijacopilot
porque justamente
os iba a comentar esto
claro
¿qué pasa con esto?
que tendríamos que mirar
si realmente
podemos ir a la siguiente
¿no?
lo que hacemos
para ir a la siguiente
es
voy a recuperar
en cuál estamos
actualmente
todas las preguntas
que tenemos
la próxima pregunta
va a ser
question más uno
y entonces vamos a ver
vale
si next question
todavía está por debajo
de la longitud
de todas las preguntas
entonces sí que lo vamos a hacer
y esto es importante
de que lo vamos a tener
que arreglar
tanto
a la hora de gestionar
el estado
como visualmente
que también lo haremos
¿vale?
pero es importante
porque de esta forma
evitamos el error
en el caso de que
alguien llame esto
así que primero
lo arreglamos
la lógica
del go next question
vamos a arreglar
aquí también esto
go next question
y go previous question
¿vale?
para que esté bien tipado
y ahora esto
de ir a la siguiente
y a la previa
vamos a utilizarlo aquí
así que tendríamos
el go next question
lo sacamos de aquí
y el
const go previous question
lo sacamos de aquí
y con estas dos
funciones
pequeñitas
vamos a crear aquí
con el stack
este que hemos visto antes
stack
vale
stack stack
vamos a utilizar
dos botones
¿vale?
aquí
joder
es que me lo está
haciendo solo
uno
para ir detrás
vamos a utilizar
el arrow
back
arrow back
ios
hostia no sé
ios new
vale
vamos a utilizar este
y vamos a utilizar
hostia
el stack no me lo ha
no me lo ha importado
el icon button
tampoco me lo ha importado
vale
y vamos a utilizar
lo mismo
esto mismo
lo vamos a utilizar aquí
pero fijaos
veis que tiene el disable
le hemos puesto el disable
de que si el current question
es cero
no podemos ir para atrás
y si el current question
el current question
es mayor
a
questions
questions
punto length
menos uno
¿vale?
entonces tampoco
podremos ir a la siguiente
así que
porque ya estaremos
en el final
y este
arrow
next
no
next
forward
creo que es
forward
ios
¿vale?
vale
aquí tendríamos
los dos componentes
¿vale?
aquí tenemos
estos dos componentes
y este
con next question
lo ponemos aquí
¿vale?
y ahora
vale
ya podemos ir
para atrás
y para adelante
¿vale?
ya podemos ir
para detrás
para atrás
y para adelante
y cuando llegamos
al final
cuando llega al final
se me ha quedado
se ha quedado ahí
como
como que nunca
lo
ahora
ahora sí
era mayor o igual
¿vale?
bueno y podremos
poner aquí en medio
por si queréis
current question
más uno
question length
para indicar
¿vale?
10 de 10
y así indicamos fácilmente
en cuál estamos
lo que estamos saliendo aquí
estamos haciendo
básicamente esta aplicación
¿eh?
y con confeti
entonces
ya tenemos
una forma
de ir a siguiente
y todo esto
¿vale?
a true
vamos aquí
y fíjate que cuando vuelves
se ha guardado
este estado global
¿vale?
entonces podríamos
volver aquí
acá
yo creo que le faltaría
un tema de información
¿no?
aquí creo que nos sale
pero lo vamos a hacer
lo vas a ver
y aquí vas a ver
la gracia
que tiene también
Zustan
cómo puedes hacer
fácilmente
leer la información
que tenemos
en estado global
y hacer cosas
muy chulas
por ejemplo
en un momento
ponemos aquí
footer.tsx
vamos a crear aquí
un pequeño footer
que nos permita
pues saber
cuántas hemos contestado
bien
cuántas hemos contestado
mal
y todo esto
vamos a hacer aquí
return
footer
hostia
he hecho la mezcla
otra vez
me encanta
me encanta la mezcla
de cons
con lo otro
vale
pues el footer
hacemos el style
margin
voy a poner
voy a hacerlo así
aunque seguramente habría algún componente
en material
con que lo podríamos hacer
¿vale?
vamos a poner strong
y vamos a poner aquí
por ejemplo
las que tenemos bien
aquí tendríamos
las correctas
y tal
¿cómo sacamos aquí?
correct
las correctas
vale
¿qué hay que hacer?
primero
questions
sacamos las questions
del use question store
o sea del estado global
use question store
state
state.questions
¿vale?
sacamos primero esto
vamos a leer
cuántas tenemos correctas
vamos a empezar
vamos a poner todo cero
correct
cero
let
incorrect
cero
let
que no han sido contestadas
cero
¿vale?
y esto lo podrías hacer
de diferentes formas
yo voy a utilizar un for each
que es un momento
y en cada cuestión
vamos a decir
bueno
si la cuestión
el user selected answer
es null
significa
que no ha sido contestada
así que más más
si la cuestión
el user selected answer
es igual
al correct answer
entonces
es correcta
de hecho
voy a sacar esto
de cada una
para que
salga más
sea más fácil de leer
¿vale?
y si el
bueno
y si no
claro
podríamos hacer esto
if
podríamos hacerlo con else if
y entonces poner
user selected
bueno
podríamos hacerlo de diferentes formas
esta sería otra
para evitarnos
justamente que
porque son tres estados diferentes
¿no?
si no
podrías utilizar el else if aquí
y entonces esta ya te queda de gratis
entonces esta ya te queda de gratis
le pones else
esto asignado
pues aquí tendríamos las correctas
las correctas
le vamos a poner aquí una separación
vamos a decir
las incorrectas
incorrectas
otra separación
y
question mark
y le ponemos las
un answered
¿vale?
y este footer
lo vamos a utilizar
en el game
sí
y vamos a ponerle aquí el footer
footer
¿vale?
vale
vamos a poner aquí
correctas
incorrectas
y
sin responder
¡pam!
vale
no lo veis
porque queda encima mi cara
pero ahora sí
lo tendríamos en un momento
¿no?
tendríamos aquí
cero correctas
cuatro incorrectas
seis sin responder
ya lo tendríais
hemos leído el estado
en un momento
oye todavía no tengo ni una correcta
a ver esta
cero
esta sería el 333
ojo
una correcta
y mirad
que
esto es un estado global
o sea está leyendo
del estado global
se está sincronizando
tanto la paginación
que aquí aparezca la correcta
que aquí salga el número
o sea lo estamos leyendo
y no lo estamos pasando
en ningún sitio
no lo estamos pasando
en ningún sitio por props
sino que simplemente
entre uno y otro
fijaos que cada vez
que yo contesto una
aquí cambian las cosas
¿veis?
ha cambiado incorrectas
y tal
y todo con un estado
totalmente global
vamos a hacer otra cosa
porque fijaos que
cuando refrescas
ah que por cierto
esto que hemos hecho aquí
podría ser
un custom hook
questions
data
esto lo sacáis de aquí
hacéis esto
correct
correct
insert
un answer
hacéis esto
y esto ya es un custom hook
que lo podéis utilizar
en cualquier sitio
esta es una de las cosas
bonitas
que tiene React
la facilidad
de extraer
lógica
esto ya lo podéis
meter en un custom hook
que estos son cosas
que hemos ido aprendiendo
en todas estas clases
use questions
data.ts
hacéis esto
export
esto hay que importarlo
vale
importamos de aquí
además
de verdad
lo he hecho con TypeScript
pero
¿cuánto?
¿cuánto hemos tipado?
si casi no hemos tenido
que escribir TypeScript
y esto es lo mejor
la mejor forma
de escribir TypeScript
es el hecho de
fijaos que lo he tipado
en un solo sitio
en un solo sitio
y ya tengo las questions
en todos los sitios
y no se me está quejando
de nada de tipos
en ningún sitio
en ningún lado
¿sabéis?
o sea es increíble
el hecho de cómo de potente
es esto
de que casi no
hemos tocado tipos
y fijaos aquí
que incluso
este use questions data
que así
no hace falta
que miréis
si utilicéis la store
esto
ya viene todo tipado
o sea es que está
todo perfecto
increíble
¿no se puede hacer
const questions?
sí que se puede
muy buena pregunta
¿vale?
que dice
¿por qué no haces esto?
¿no?
¿por qué no hago esto?
questions
¿por qué no hago esto?
use questions
store
state state
¿por qué no hago esto?
vale
o sea
esto sería
acceder a todo el estado
y solo
traerte
la propiedad
questions
¿por qué no hago esto?
y sí que hago
lo de arriba
porque estoy haciendo
esto de aquí
esto tiene una explicación
bastante
sencilla
pero que tiene muchas
implicaciones por dentro
pero
lo que está pasando aquí
es que tú
lo que está pasando
en esta línea
es que
estás
observando
los cambios
de
todo el estado
lo que le estás indicando
a Azustan es
oye
quiero que me informes
de cualquier cambio
que haya en el objeto
state
en todo el estado
¿entiendes?
entonces en cualquier cambio
que tengas del estado
esto
va a volver a
re-renderizarse
va a volver a ejecutar
un renderizado
del componente
tú imagínate
que tuviésemos
otra cosa en el estado
tengamos un estado
mucho más complicado
en el que al final
tendríamos
yo que sé
pues un objeto
que se va generando
todo el rato
o lo que sea
aquí tendríamos este problema
podríamos llegar a hacer
de aquí
le puedes llegar a pasar
por ejemplo
lo de shallow
que es una cosa
de Azustan
para que te vaya haciendo
constantemente
una comparación profunda
pero
no lo deberías
o sea
no lo deberías hacer
no deberías hacer esto nunca
porque si no
lo que estás
lo que estás haciendo
es demasiado complejo
o sea
estás haciendo
que sea Azustan
el que haga el trabajo
para ti
no lo hagas
siempre que puedas
tienes que ser claro
sobre lo que quieres extraer
sobre la parte del estado
que quieres observar
porque si no puedes ver
que a lo mejor
vas a tener
como cálculos innecesarios
re-renderizados
que no necesitas
¿vale?
así que siempre que puedas
saca solo del estado
y ahora
lo que le está diciendo Azustan
es
oye del estado
cada vez que cambie questions
quiero que me informes
entonces cada vez que cambie questions
pam
esto se volverá a renderizar
punto
y vas a tener
mucho menos renderizados
innecesarios
porque si no
cualquier cambio de toda la store
se re-renderizaría
¿ok?
ahí lo tendría
aparte de esto
fijaos que ahora
cada vez que renderiza
que volvemos a
a refrescar
pues claro
empezamos de cero
claro yo estoy aquí
refresco
empiezo de cero
pues ojo
porque esto
os va a volar
la cabeza
os va a volar la cabeza
porque una cosa
que podemos hacer
muy fácilmente
es la persistencia
de los datos
con el local storage
para eso
lo que podéis hacer
es tan fácil
tan fácil
como ir aquí
a vuestra store
importar
persist
de
Zustan
Midelware
porque Zustan
también puedes crear
tantos Midelwares
como quieras
¿vale?
pues Midelware
significa que cada vez
que se vaya a cambiar
algo de la store
pues haga algo ahí
¿y qué es lo que hace
este persist?
pues lo que hace
es capturar
todos los cambios
que quieres hacer
en la store
y lo sincroniza
con el local storage
con el session storage
en realidad lo sincroniza
con lo que tú quieras
se lo podrías pasar
se lo podrías informar
y vas a ver
que es absurdamente sencillo
lo único que tenemos que hacer
es envolver
nuestra store
¿ves esta store
que tengo por aquí?
toda este callback
que tengo aquí
lo único que tengo que hacer
es decirle
oye
esto
quiero que lo persistas
¿vale?
lo envolvemos aquí
lo cerramos
espérate
que este es complicado
¿vale?
porque tenemos este return
este aquí
¿vale?
ahora le vamos a poner
un nombre
a este
a esto
que es questions
y esto
lo cerramos aquí
no
me equivoqué
me equivoqué
¿veis?
este lo tengo bien
este persist
vale
o sea que este
es aquí donde va
aquí tenemos el name questions
este aquí
este aquí
vale
ahora sí
¿no?
ah sí, sí, sí
ahora sí
ahora sí
ahora lo tengo bien
ahora lo tengo bien
o sea aquí lo que le estamos dando
es un nombre
a lo que queremos persistir
porque imaginad que tenéis más de una store
pues tenemos que darle algún prefijo
para que sepa
dónde lo queremos guardar
¿vale?
además aquí también
podríais decirle
get storage
y aquí le podríais indicar
dónde lo queréis meter
por ejemplo
local storage
session storage
podríais ahí
meter diferentes sitios
donde cumpla la API
por defecto
lo hace en el local storage
ahora bien
¿veis que se está quejando?
esto en realidad
es typescript
que se está quejando
esto es porque ahora
el persist
está envolviendo
el set get
y todo esto
lo que deberíamos
si no me equivoco
es que esto
como devuelve una función
tendríamos que poner esto aquí
y ya lo tendríamos tipado
¿vale?
así que si te da problemas
el persist
que sepas esto
tenemos aquí el create
que en realidad
es el state
que tendríamos aquí
y esto
sería porque
estamos ejecutando
este persist
que a su vez
está devolviendo una función
¿vale?
es un poco más
más como raro
pero con que sepáis
que el persist
se está devolviendo
una función
que por eso
tenemos que poner esto aquí
pues ya lo tendremos
y ya está
con esto
ahora
si guardamos
le damos a empezar
¿cuál es el resultado?
false
vale
era true
¿vale?
y ahora
nos vamos al siguiente
this
ah no sé qué
undefined
¿vale?
¿cuál es la salida
de este código?
1, 2, 3
esto es
11
¿vale?
el resultado de lo siguiente
esto es false
vale
si yo ahora
refresco
fijaos que he refrescado
y es que me deja
exactamente igual
me deja en el mismo sitio
voy a la página 5
refresco
¿ves?
en el mismo sitio
cierro la pestaña
entro
en el mismo sitio
o sea
ha persistido
todos los datos
sin necesidad
de hacer absolutamente nada
o sea
increíble
¿dónde ha guardado
toda esta información?
como os he dicho
por defecto
lo guarda
en el local storage
así que si vamos aquí
al local storage
que a ver si lo encuentro
¿dónde está el local storage?
¿aquí?
vale
pues aquí tendríais
donde lo está guardando
¿veis?
questions
y aquí tiene todo el estado
aquí todo este estado
es el estado
con el que está iniciando
también debería tener
un botón de reset
hacemos el botón de reset
en un momentito
porque nos vamos al footer
¿vale?
vamos al footer
y en el footer
vamos a ponerle aquí
un button
¿vale?
que cuando haces click
vamos a llamar aquí
a un método reset
que ahora mismo
no lo tengo todavía
pero ahora lo hago
¿vale?
hacemos el reset
resetear juego
y este reset
lo tenemos que crear
¿no?
o sea que hacemos el reset
lo sacamos del
useQuestionsData
no, del data no
useQuestionsStore
de la store
¿vale?
de la store
y vamos a la store
questions
y creamos el reset
en un momento
que el reset
sería tan fácil
como setear
el current question a cero
y el questions vacío
con esto
a ver
aquí es que he puesto uno de más
¿no?
sí, vale, ya está
con esto
ya tendríamos aquí
el resetear juego
voy a arreglar un poquito más
este footer
vamos a poner esto
en un deep
tip
style
margin
top
16 pixels
16
pa pa pa
movemos esto para aquí
esto para acá
¿vale?
ya tenemos ahí nuestro
resetear juego
¿vale?
le damos a resetear
y ya está
reseteado el juego
refrescamos
funciona
empezar
empezamos a darle
refrescamos
se queda ahí
quiero resetear
resetear
ya está
y de nuevo
empezar
o sea, hemos hecho la aplicación esta
de hecho la nuestra tiene resetear
que esta no lo tiene
¿cuál es la diferencia con SWR?
ventajas
es que
¿cuál es la diferencia?
es que una es
de estado
para manejar estados
asíncronos
globales
y este
es para estados
globales
que pueden ser asíncronos
o puede ser lo que te dé la gana
por ejemplo
¿cómo guardas en SWR?
esto
¿cómo haces esto en SWR?
go previous question
para que visualmente vaya a la siguiente
¿qué haces?
¿cómo haces este del select cancer?
sin necesidad de ir
a hacer un fetching de datos
o hacer algo asíncrono
es que no es necesario
no es necesario
esto
son dos cosas distintas
una es para gestionar
estados globales
asíncronos
que es de fetching de datos
y tal
donde tengas loading, error y tal
y otro que no
midu
cuando se dice que la lógica
es preferible que esté por fuera
del componente
se refiere a que esté antes del retorno
o que esté en otro archivo
que esté en otro archivo
por ejemplo
la lógica
aquí tenemos una lógica
que hago aquí un fetching de datos
y todo esto
lo que es más interesante
en lugar de tenerlo ahí
es hacer un services
aquí questions.ts
export
const
fetch
puedes hacer incluso
bueno
vamos a hacer
get all questions
limit
y esta parte de aquí
que esto es lógica
que podrías utilizar
en cualquier sitio
pues esto
lo puedes meter aquí
y esto haces un JSON
y si el día de mañana
esto lo recuperas
de un sitio
y lo recuperas de otro
pues ya lo tendrías arreglado
ya está
esto lo puedes
te lo puedes llevar a view
y esto funciona
si tú esto lo haces
en mitad de un componente de React
tendrías que tocar
componente de React
ese es el problema
y ahora esto
ya lo puedes utilizar en view
en svelte
en lo que sea
porque es agnóstico
al framework
y esto es lo que significa
separar
la lógica de negocio
¿cómo se crean
middleware en Zustan?
para crear un middleware
lo que pasa es que es un poco complicado
por el tema este del persist
y todo esto
que me imagino que podríamos
llegar a envolver
a ver
vamos a hacer el típico logger
¿vale?
primero tienes
ves
primero te llega la config
y luego tendrías
el set
el get
y la API
¿vale?
o sea que
con esto
este set get API
ya podrías devolver
return
llamar al conf
bueno
¿qué es esto?
básicamente
o sea esto sería
tendrías
por un lado
en el config
le deberías pasar
una función
que recibirías
todos los argumentos
que yo creo que
es todo lo interesante
sería recibirlos así
que tendrías
antes de setear
y después de setear
o sea esto sería
new state
y aquí podrías recuperar
el nuevo estado
por ejemplo
¿vale?
y
con esto
si no recuerdo mal
deberíamos poder
envolver esto
esto
¿vale?
correct question
a ver
claro
lo malo
es que esto ahora
devuelve mal
también esto
porque esto también
debería devolver
otra función
bueno
aquí ya
se me escapa
el tema
pero vamos a ver
si funciona al menos
me parece que no funciona
crear
se crean así
que lo
a ver
lo podemos buscar
zustan
mydware
pero crear
estoy bastante seguro
que se crean así
a ver si
en la consola vemos
no puede leer
a prueba
ah
hostia
o sea
sí que está funcionando
el mydware
lo que no ha funcionado
es porque
a lo mejor estoy devolviendo
algo mal aquí
o algo
return
config set arcs
ah
coño
porque esto lo estoy
seteando mal
es que esto
claro
como le he puesto
los tres puntos
ya está
o sea
ya está
es así
logger
esto llega aquí
el método este
de config
para configurar
la store
aquí tendríamos
este sería el set
o el get
o el api
o sea
puedes utilizar
puedes sobreescribir
cualquiera de los tres
este es el set
¿vale?
si no hicieses nada
este sería el set
ahora lo que puedes hacer
es envolver el set
para por ejemplo
aquí hacer un applying
y este sería el set
original
y esto sería un mydware
lo que haces siempre
es envolver
todo lo demás
con esto
y ya lo tienes
hecho
listo
pim pam
ahora cada vez
que tú hagas
¿ves?
cada vez que hagamos
cualquier operación aquí
bueno
espérate
voy a ponerlo aquí
que se pegue
y ahora de hecho
te enseñaré el tema
de las dev tools
que también es súper interesante
porque utiliza las de redax
mira
ahora cada vez
que hagamos cualquier cosa
empezar
¿vale?
apply no sé qué
si yo le doy
apply
está aplicando este cambio
¿vale?
pues este
y este es el nuevo estado
y así todo el rato
así lo tendrías
fácil y rápido
no es el mydware
mejor del mundo
pero esto es lo que utiliza
esto es lo que hace el persist
por debajo
básicamente
¿vale?
espero que eso te haya ayudado
a ver
sí
a ver que pone en rojo
argument type
no sé si ahora
me está
me está trolleando
porque esto funcionaba bien
ahora
vale ya está
una cosa más
que está súper chula
que no os he enseñado
hemos hecho lo del reset
y todo esto
es que si tenéis
que yo creo que no la tengo
pero si tenéis la extensión esta
de la redax dev tools
la podéis utilizar también
con Zustan
hay un tema que hay que
adaptar un poquito
¿vale?
para que lo veáis
hay una cosita que hay que adaptar
pero bastante fácil
¿ves?
la instaláis
vamos a nuestro proyecto
teniendo en cuenta
que tenemos la extensión
de react dev tools
instalada
¿vale?
react
redax dev tools
esta extensión
también la podéis utilizar
con Zustan
y os va a enseñar
el estado que tiene vuestras stores
las acciones que se hacen
y todo esto
súper fácil
lo podéis utilizar
¿vale?
lo que tenéis que hacer aquí
lo que
lo único que tenéis que hacer
es pues activarlas
y para activarlas
vais aquí
vamos a
donde hemos hecho
la store
aquí
y fijaos que teníamos
en el middleware
tenemos el persist
pues también tenéis una
que es dev tools
y esto de dev tools
pues lo mismo que hemos hecho
con cualquier middleware y tal
pues la ponemos aquí
pam pam pam
y aquí lo cerramos bien
para que no se nos escape
y ya está
con esto
con esto
ya deberíais tener
si le damos aquí
a redax dev tools
¿vale?
voy a ver
si lo puedo pinear
¿dónde se pineaba esto?
ah no me acuerdo
sé que se puede sacar
aquí
vale
a sacarla aquí
pim pim pim
y vamos a hacer esto
un poquito más pequeño
vamos a poner esto aquí
vale
y vais a ver que ahora
cuando me mueva
¿veis que pone anonymous?
vale
ahora alguien dirá
hostia pero es que pone anonymous
menudo rollo
vale
cada vez que cambio página
pues aquí se ve
como está cambiando la página
te dice cuál era la anterior
el siguiente
puedes ver todo el estado
¿vale?
este como el estado
papapá
la acción
pero fíjate que la acción
pone anonymous
esto se puede arreglar
súper fácil
que además también
puedes
puedes revertir
¿eh?
puedes ir para atrás
para adelante
puedes
o sea está súper bien
porque al utilizar las devtools
puedes
volver a replicar algo
puedes tirarlo para atrás
lo puedes deshacer
esto
mira
por ejemplo
imaginad que yo hago todo esto
pam pam
voy para atrás
voy para adelante
y esto
pues aquí en las devtools
tenéis
mira
a ver
voy a mover esto por acá
para que lo veáis
¿veis aquí que hay como un play?
esto podéis ir para atrás
y va a replicar
todos los pasos que ha hecho
ahora
para arreglar
esto de anonymous
que aparece aquí
lo único que tenéis que hacer
es que aquí
donde están los set
aparte de poner esto
y esto es un poco raro
porque el segundo
es el replace
y te obliga a utilizar el false
no sé si puedes poner un define
bueno
puedes poner un define
pero bueno
debería ser false
es un rollo esto
pues entonces tienes que poner
false o un define
y luego tendrías que poner
el nombre de la acción
por ejemplo aquí
fetch
podrías poner fetch questions
fetch questions
y esto igual
pues para todas
para todas las que las quieran nombrar
no utilices el mismo nombre
porque si no va a ser un poco raro
pero aquí
false select answer
¿vale?
aquí
false
next
go next question
esto solo necesitas
si quieres utilizar
las dev tools
y quieres tener nombradas
las acciones
¿vale?
que no hace falta que lo hagas
si no quieres
entonces
ahora que tú vas siguiente
no sé qué
null
¿ves?
ahora sí que aparece el nombre
reseteamos
te sale el reset
puedes ir para adelante
para atrás
esto es brutal
la verdad es que esto es brutal
el tener como una máquina del tiempo
de todo tu estado
y así puedes replicar
todo lo que
lo que has hecho
o sea
tremendo
¿por qué pudiste mostrar
las dev tools de Redux?
buena pregunta
Zustan no utiliza Redux
pero puedes utilizar
las dev tools de Redux
¿y esto cómo lo hace?
pues esto lo hace
con una técnica
que se llama bridge
o puente
lo que hace es
está utilizando Zustan
que no tiene nada que ver con Redux
pero ha creado un puente
en el que simula
que es Redux
en algunas cosas
para que funcionen
las Redux dev tools