This graph shows how many times the word ______ has been mentioned throughout the history of the program.
Muy buenas tardes, ¿qué tal? Espero que estés súper bien, que estés preparado o preparada porque hoy tenemos curso de React.
Bueno, hoy vamos a estar desarrollando una app desde cero, un clon de Google Translate con la API de ChatGPT, React y TypeScript.
Tres, lo vamos a poner de código abierto en este nuestro querido repositorio.
Tenemos este repositorio que le hemos llamado Aprendiendo React, donde aquí tenéis una de proyectos,
una de proyectos que hemos hecho ya, todos estos proyectos, todos estos proyectos los hemos hecho aquí en vivo y en directo, ¿vale?
Os lo voy a ir explicando, lo vamos a hacer con TypeScript, con la API de ChatGPT, vais a ver cómo lo utilizamos,
cómo le sacamos justamente la gracia a todo esto.
Vamos a hacer también el desplegable este, no lo haremos así porque este es bastante más complicado, lo haremos mucho más sencillo.
Vamos a hacerle un test para que veáis cuál es el test que yo le haría.
Muchas veces en pruebas técnicas, esto no es una prueba técnica, pero muchas veces en pruebas técnicas os hacen esta trampa.
¿Cuál es el test que harías? Bueno, pues yo voy a enseñar cuál es el test que yo creo que haría si me diese tiempo en una prueba técnica.
Y el switch del medio también, sí, el switch del medio este lo vamos a hacer, si está tirado, lo vais a ver, está tirado, está tirado.
Esto lo va a tener, ¿vale? Va a tenerlo de detectar idioma, también lo vamos a hacer porque vais a ver que es muy fácil.
Así que venga, vamos a empezar con el proyectito.
Vais a vuestra terminal favorita, lo que voy a hacer como siempre, npm, read, write, npm, create, beat y la última versión.
Esto nos va a hacer las preguntas de siempre, que vamos a hacer el Google Translate Clone.
Aquí en elegir, obviamente, vamos a utilizar React y, ojo aquí, vamos a seleccionar TypeScript más SWC.
SWC lo he explicado muchas veces, pero básicamente es un transpilador de código.
Es como el Babel, que lo que hace es que va a entender el JSX, va a entender el JavaScript del futuro
y lo va a compilar a un JavaScript que puedan entender los navegadores, ¿vale?
Le damos aquí, Google Translate Clone.
Hacemos el npm install, va a tardar un poquito, pero bueno, vamos a hacer el npm install.
Vale, vamos a abrir este proyectito por aquí.
Lo primero que, muchas veces lo primero que hago, ya sabéis, y esto lo recomiendo siempre que lo hagáis,
es instalar todas las dependencias que vais a necesitar.
Y en este caso vamos a utilizar, vamos a hacer npx slint init.
Vamos a inicializar el linter, porque trabajar sin linter es un rollo.
Hay muchas formas de inicializar el linter, pero yo os recomiendo que ejecutéis este comando
npx slint-init si tenéis problemas, porque es muy fácil y lo único que tenéis que hacer
es simplemente seleccionar lo que queréis hacer.
Por ejemplo, aquí le dices, quiero chequear la sintaxis, encontrar problemas y forzar un estilo de código.
¿Qué queremos utilizar?
Vamos a utilizar JavaScript Modules.
¿Qué framework utilizamos?
Utilizamos React.
¿Utiliza TypeScript?
Sí que lo utiliza.
¿Y ahora, dónde va a ejecutarse esto?
En el navegador voy a utilizar un estilo popular y a mí me gusta el de estándar, que es sin punto y coma.
Si no te gusta este, utiliza otro.
¿Y en qué formato queremos que esté la configuración?
En JavaScript.
Esto lo que va a hacer es instalarnos un montón de paquetes y añadirnos unas cuantas configuraciones.
Vamos a utilizar npm, que es lo que estamos utilizando para instalar las dependencias.
Si vamos aquí a .tsx, ¿vale?
¿Veis?
¿Veis?
No me está, no me detecta ahora mismo el linter.
El problema, si le dais aquí, os lo dice.
¿Ves?
Le podéis dar aquí y aquí te dice, oye, que no sé qué, no sé cuánto.
¿Cuál es el problema?
El problema es que no tenemos el parser options project, pero esto es un momento.
Como estamos utilizando el linter con TypeScript, lo único que tenemos que decir es, oye, en
el slint rcjs, cjs este, en el parser options le tenemos que decir dónde está nuestro proyecto.
Creo que era project y aquí ponemos tsconfig.json para que vea este archivo de aquí que tiene
la configuración de TypeScript.
Si nunca has visto TypeScript, no te preocupes, porque lo voy a explicar hoy paso a paso.
No es difícil de entender y además vamos a intentar escribir el mínimo TypeScript necesario.
Vamos a intentar utilizar más JavaScript que TypeScript y donde necesitemos TypeScript, pues
lo haremos.
Y así verás que tiene mucho sentido, que es mucho más cómodo.
Pues ahora que ya tenemos esto, esto con esta configuración del project, ahora sí
veis que está todo en rojo.
Yo ya tengo mi extensión del linter, que cuando guarde, pues se me está actualizando
todo.
Vamos a arreglar unas cuantas cosas en la configuración del linter.
Lo primero, el missing return type on function.
Veis que se me queja de esta regla, de TypeScript explicit function return type.
Esto lo vamos a desactivar, ¿vale?
¿Por qué lo vamos a desactivar?
Porque realmente es lo que os he dicho.
Vamos a intentar escribir el mínimo TypeScript posible, para que no solo sea entendible,
sino que si ya tiene algún tipo de inferencia, pues vamos a fiarnos de ella.
Así que esto lo ponemos en off.
No vamos a poner el tipo de dato que devuelve la función porque ya nos lo dice.
Ya nos está diciendo que es un elemento JSX.
Luego aquí nos dice que React tiene que estar en el scope, ¿ves?
React tiene que estar en el scope cuando use JSX.
Esto no es del todo correcto ya, porque como ya sabéis, esto ya no es necesario,
porque con las nuevas versiones de React lo que hace es que esto lo hace automáticamente.
Así que vamos a desactivar también esta regla de React en JSX scope.
Esta regla la vamos a desactivar también.
Ya veis que, bueno, vamos a activar, vamos a arreglar algunas de las reglas a mano,
las vamos a desactivar a mano, pero luego ya no nos tenemos que preocupar más de esto.
Esto lo vamos a eliminar, que esto no lo vamos a necesitar, ¿vale?
Esto lo quitamos, esto también.
Vamos a poner aquí nuestro Google Translate.
Borramos esto, esto también lo quitamos.
Creo que con esto ya deberíamos tener todas las reglas que queríamos quitar.
Si hay alguna que se nos ocurre, pues luego la quitamos y ya está.
Lo bueno es que ya tenemos nuestro linter funcionando, ¿veis?
Le doy a guardar y me lo quita.
Esto es una gloria.
Así que ahora sí podemos continuar con lo nuestro.
Ahora que ya tenemos el linter, lo que quiero utilizar es el React Bootstrap.
Yo no soy un fan de React Bootstrap, pero bueno, vamos a hacer una aplicación muy sencilla
y nos viene bien porque ya viene con algunos componentes que son muy sencillos,
pero que van a dar el pego.
Por ejemplo, tienes alertas, acordeones, batch.
La verdad, de cómo funciona React Bootstrap y similares,
es que lo que utilizas es un componente directamente.
Lo vamos a poner, importar, usar y listo.
Vamos a instalar estas dos dependencias que nos está pidiendo por aquí.
Instalamos React Bootstrap y Bootstrap.
Le decimos que nos lo guarde la versión exacta.
Ponemos el menos E y ya está.
Aparte de instalar esto y tener que importar los componentes a mano,
también tenemos que importar los estilos.
Así que estos estilos que tenemos por aquí, nos vamos a la app
y los vamos a importar aquí mismo.
Vamos a quitar también los estilos estos que tenemos por aquí.
Vamos a quitar estos.
Y este lo voy a dejar, pero lo voy a dejar más pequeñito.
Con el padding y este lo quitamos.
Estos serían un poco todos los estilos que necesitamos ahora mismo.
Vamos a levantar el proyecto ya, npm run dev, para levantar el modo desarrollo.
Nos vamos a 51.73.
Vamos a hacer una cosa diferente.
¿Por qué?
Porque muchas veces cuando trabajamos y creamos una aplicación desde cero,
nos lanzamos al cuello a hacer la parte visual.
Que está bien, no pasa nada, no hay ningún problema.
Pero hoy le vamos a dar la vuelta.
¿Sabéis?
Vamos a darle la vuelta porque lo que vamos a hacer es,
vamos a pensar más en la lógica.
Primero, vamos a crear la lógica y luego vamos a ver lo visual.
¿Por qué es esto?
Yo creo que a veces es una buena práctica,
igual que hay gente que hace TDD, que es Testing Drive and Development,
que haces los tests guiado, el desarrollo lo guías por las pruebas, por el testing.
Vamos a hacer primero la lógica del estado.
Vamos a hacer primero el reducer,
porque nos va a simplificar mucho pensar en nuestros componentes visuales.
Y vas a ver por qué.
Aquí cuando tenemos este Google Translate,
tendríamos que pensar las cosas que necesitamos en el Google Translate.
Por ejemplo, necesitaríamos guardar cuál es el idioma original,
cuál es el idioma destino, el texto del usuario y el texto resultado.
También si está cargando, porque cuando pones aquí hola mundo,
hay un momento que se pone así como traduciendo.
¿Veis?
Pues necesitamos saber cuándo está cargando.
Así que necesitaríamos también,
¿desde dónde viene?
O sea, tendríamos como cinco estados, cinco estados diferentes.
Como son cinco estados, en lugar de utilizar el useState,
vamos a utilizar un reducer directamente,
que va a ser mucho más fácil a la hora de pensar justamente todo el estado que queremos crear.
Así que vamos a crear directamente el reducer.
Lo podría crear aquí, directamente.
Mira, initialState.
¿Cuál va a ser el estado inicial?
Vamos a tener el lenguaje de inicio,
que vamos a hacer que sea auto,
que automáticamente vamos a detectar el lenguaje,
y el destino vamos a poner que sea inglés,
para que siempre nos funcione de primeras.
El texto original vamos a poner un string vacío,
una cadena de texto,
y el resultado vamos a poner también un string vacío.
Y vamos a tener el booleano para saber si estamos cargando o no estamos cargando.
Ahora que ya tenemos el estado inicial,
necesitamos pensar en cómo queremos transformar nuestro estado.
¿Cuáles son las acciones que puede hacer el usuario para transformar el estado?
Por ejemplo, puede cambiar el idioma, ¿no?
Aquí puede cambiar el idioma y poner georgiano.
Puede cambiar el idioma de destino.
Puede cambiar este texto.
El usuario no lo cambia,
pero tendremos que tener una forma de cambiar aquí,
pues para saber si ya tenemos un resultado y mostrárselo.
Y también el del loading, ¿no?
Tenemos que saber cuándo tenemos que cargar o cuándo no tenemos que cargar.
Aunque eso no es un estado, una acción.
Vale, tenemos el estado inicial.
Ahora tenemos que pensar en las acciones,
que ya os he contado las acciones, ¿vale?
¿Qué es un reducer?
Un reducer recibe dos cosas, ¿no?
El estado, el estado que tengamos, y la acción.
Pensad que, vale, tendríamos aquí las actions, ¿vale?
Tendríamos aquí el reducer, reducer.
Vamos a poner aquí también el useReducer.
¿Qué se le pasa al useReducer?
Al useReducer, que lo vamos a ver después,
este es el hook de React,
a esto se le pasan dos cosas.
Estas dos cosas se le pasan al...
Esto se le pasa al useReducer.
Esto aquí y esto aquí, ¿vale?
Al useReducer tú le pasas el estado inicial y le pasas el reducer.
¿Qué es lo que hace el reducer?
El reducer, al final, lo que hace es que cada vez que tú llamas a una acción,
esta acción tú lo que haces es despacharla
y esto se lo pasas con un dispatch, ¿vale?
Con un dispatch.
Y esto le llega al reducer.
El reducer lo que hará cuando llegue esto es generar un nuevo estado,
generar un nuevo estado,
y este estado,
esto aquí y esto aquí, ¿vale?
Este action lo vamos a poner aquí,
y este aquí tenemos el state.
Entonces, generar un nuevo estado,
y este nuevo estado se va para acá.
Entonces, al reducer,
que lo vamos a tener aquí,
el useReducer,
recibe el estado inicial y un reducer.
¿Qué nos devuelve esto?
Nos devuelve el estado
y nos devuelve...
Más que action, esto sería el dispatch, ¿no?
Dispatch,
y aquí vamos a poner la action
con información.
Ahora cuando lo veáis en código lo veréis todo más claro.
El dispatch,
tú haces un dispatch,
es como decirle,
mira, quiero que hagas esto,
y tú le pasas la acción con información.
Por ejemplo,
un dispatch podría ser,
vamos a poner un ejemplo aquí,
que sería setLanguage.
Este podría ser un dispatch,
y le pasaríamos aquí la información,
como por ejemplo,
setLanguage en español.
Cuando esto le llega al reducer,
dice, vale,
tú lo que quieres es actualizar el lenguaje,
aquí tenemos una máquina
que genera un nuevo estado,
y cada vez que genera un nuevo estado,
pues tenemos el state
que se está volviendo a actualizar,
y este state,
lo que haría sería
volver a renderizar
en nuestro componente.
Render component.
Render component.
Cada vez que cambia,
se renderiza el componente.
Esto sería
lo que hacen nuestros reducers,
que ahora mismo parece
como un montón de,
no sé,
de flechas y tal,
pero que cuando lo piensas
tampoco es tan complicado,
porque lo único que tienes que hacer aquí
es como crear
cada vez que tienes una acción
un nuevo estado
para que se renderice el componente.
Ahora lo vamos a ver con código,
y lo vais a ver mucho más clara.
Ya tenemos
el estado inicial,
que es justamente este.
Este de aquí
los voy a
numerar
para que veáis
y lo vais a entender tan bien
que no vais a tener más dudas
en la vida.
Este sería el 1
del croquis.
Create a initial
initial state.
Esto sería
dos
create a reducer.
Así que el dos
lo tendríamos,
esto lo tenemos aquí.
Ahora,
tenemos que utilizar
el hook de React
de youReducer.
¿Dónde lo tenemos que hacer?
Pues aquí.
Tenemos youReducer
y ¿qué hemos dicho
que hay que pasarle?
Hay que pasarle
por un lado el reducer
y por otro
el initial state.
Este sería el 3.
Ya tendríamos,
esto sería el 3.
¿Vale?
El hook de este,
el 3.
Vamos a usar
el estado,
el hook
youReducer,
¿vale?
Este sería el 3.
¿Qué hemos visto
que nos devuelve esto?
Nos devuelve
el estado
y el dispatch.
Pues entonces tenemos aquí
tanto el state
como el dispatch.
Que ahora veremos
cómo arreglamos esto
para que funcione
todo correctamente.
Esto sería,
pues bueno,
no voy a poner 4 y 5
pero ya lo entendéis.
Ahora,
lo importante
es cómo
se generan
los nuevos estados.
La magia que hace
justamente el reducer.
El reducer lo que hace
es recibir
el estado
que tiene
y una acción.
O sea,
que cada vez
que reciba
una nueva acción,
como por ejemplo,
mirad,
voy a haceros
un ejemplo
bastante fácil.
¿Veis este,
esto que me habéis dicho?
¿Vas a hacer esto
del interchange?
¿Veis que cambia
entre uno y otro?
Vamos a hacer este el primero
que es bastante interesante.
Para hacer el cambio
lo que tenemos que
primero saber
es cuál es el tipo
de la acción.
Así que recuperamos la acción.
Podríamos tener un switch,
yo lo voy a hacer con un if
porque no me gustan los switch
pero si te gusta el switch
pues hazlo con switch.
Que si el tipo de la acción
es igual a
interchange languages
lo que vamos a hacer
en el estado
vamos a devolver
un nuevo estado
donde el from language
ahora pasa a ser
el to language
y el to language
pase a ser
el que teníamos
en el from language.
Así que cuando hemos recibido
la acción
de este tipo
lo que estamos haciendo
es generar un nuevo estado
donde se intercambia esto.
O sea,
ya estamos pensando más
en lugar de ir directamente
a la interfaz
que es muy interesante
pero no lo que le da vida
estamos pensando más
en la lógica.
Y esto es tan fácil
como esto.
Ahora,
si no hay ningún tipo
lo que podemos hacer aquí
es simplemente
devolver el mismo estado.
O sea,
un reducer
siempre tiene que devolver
un nuevo estado.
Si la acción
es de intercambiar lenguajes
vamos a generar
este nuevo estado
y lo devolvemos.
Si no lo tenemos
contemplado el tipo
y no hemos encontrado ninguno
devolvemos el mismo estado.
¿Vale?
Así que ya nuestro reducer
está funcionando.
Y esto lo deberíamos hacer
con todos y cada uno de ellos.
Por ejemplo,
¿qué más tendríamos que hacer?
Tendríamos que hacer
if type
y podríamos hacer
el set from language.
¿No?
O sea,
cuando queremos cambiar
este input
¿vale?
y queremos poner otro
esto tenemos que actualizar
el estado.
¿Qué tenemos que hacer?
Devolver
el mismo estado
que teníamos
pero el from language
va a venir
justamente
del action.payload.
¿Qué es el payload?
Pues es lo siguiente
que le vamos a pasar
en cada acción
porque hay veces
que no necesitamos
pasarle ningún payload
pero hay veces
que queremos
no, no
quiero que cambies el idioma
y este es el idioma
que quiero que cambies.
Entonces,
ese sería el payload.
Es como
lo que está enviando
de información
de acción
para poder actualizar
el estado.
Así que en lugar
del from language
de sacarlo
de la nada
sacamos de aquí
del action.payload
y esto
pues lo repetimos
otra vez
con el para cambiar
por ejemplo
hay puesto dos iguales
esto deberían ser tres
¿vale?
Aquí type
y ponemos
set to language
para hacer lo mismo
pero para cambiar
el de destino
el idioma
de destino
o sea,
ya tendríamos cambiando
este también de aquí
el de la derecha
¿Qué más tendríamos que hacer
cuando queremos cambiar
este texto
cada vez que escribimos
este texto?
Pues venga
lo hacemos igual
if type
el tipo de la acción
es set from text
entonces
pues nada
cambiamos el estado
del from text
es lo que le pasaremos
como payload
y luego
el resultado
¿vale?
Pero ahora fíjate
porque vas a ver
una cosa muy interesante
muy chula
de esto
esto cuando tengamos
el resultado
dejamos todo el estado
solo cambiamos el resultado
con el payload
esto
esto está bien
o sea,
en general está bien
pero
pero hay una cosa
más interesante
sobre las acciones
porque tú viendo esto
dirás
bueno,
pero es que siempre
hace más o menos
lo mismo
excepto por este
más o menos
está haciendo lo mismo
todo el rato
de hecho
esto
action.payload
no es necesario
porque ya lo estamos sacando
aquí arriba
¿vale?
lo estamos sacando aquí
o sea que no
necesitamos
tú viendo esto dirás
bueno,
pero siempre estás actualizando
un estado
pero tienes que pensar
más allá
¿por qué?
porque tienes que pensar
que a veces
la acción
de un usuario
puede ser
partes del payload
o puede cambiar
otras partes del estado
simplemente porque
esa acción
lo necesita
por ejemplo
si lo piensas fríamente
cada vez
que cambiemos
el set
from text
este
el set
from text
este
cuando cada vez
que cambiamos
este texto
ves que se pone
el loading a true
pues igual
deberíamos cambiar
aquí el loading a true
y así
cada vez que cambiamos
el texto
ya vamos a mostrar
el estado de carga
y lo mismo
cuando seteemos
el resultado
aquí podemos poner
el loading a false
y ya está
de esta forma ya
estamos haciendo algo extra
o sea la acción
que hace el usuario
no significa que
simplemente va a actualizar
esa parte
sino que va a ir más allá
lo mismo podríamos hacer
con set from text
también cada vez que escribe
a lo mejor
podríamos pensar
aquí no lo hace
pero podríamos pensar
que cada vez que escribe
que quite esto
¿no?
que lo quite
que cuando escribe
pues que quite esto
y lo elimine
entonces aquí
lo que podríamos hacer
es poner que cada vez
que escribe el usuario
pues poner el resultado
con una cadena de texto vacía
con esto
ya estamos haciendo
una actualización del estado
que es totalmente
agnóstica al usuario
o sea el usuario no lo ve
ya tenemos problemas
aquí de
de tipos
tipos
bueno
estamos utilizando TypeScript
y fíjate que nos dice
que el parámetro state
tiene implícitamente
el tipo any
o sea claro
no sabe
qué es lo que espera
de estado aquí
esto lo vamos a arreglar
y es súper fácil de arreglar
hay dos formas
de que lo podríamos arreglar
una le podríamos decir
que el state
es el type of state
type of initial state
y nos podemos quedar
súper a gusto
porque aquí lo que estamos
diciendo a TypeScript
es que el state este
que le llega aquí
es del mismo tipo
que este objeto
así que si me pongo encima
fíjate que ha detectado
cada uno de los pasos
que tenemos aquí
el from language
es un string
el to language
o sea así de fácil
ya tendrías algo de tipado
el complicado
sería el action
pero antes de seguir
con el action
vamos a arreglar esto
a ver
esto lo puedes hacer así
no habría ningún problema
pero yo creo
que lo mejor que puedes hacer
en realidad
sería evitar este tipo de cosas
vamos a crear un fichero
que es types.d.ts
.d porque es solo de definiciones
o sea no va a tener código
de TypeScript como tal
y aquí
podríamos tener más bien
como el estado
mejor
como
ya definido
o sea
podríamos decirle
oye el tipo
del estado
es tal que así
¿no?
pues le podríamos decir
que este estado
que tenemos por aquí
pues esto es un string
que el to language
esto es un string
aunque esto ya veréis
que esto lo vamos a arreglar después
porque no es exactamente así
aquí podríamos el front language
y esto
al final es cualquier string
y queremos limitarlos
luego veremos
como los podemos limitar
el tipo del estado
ya nos dice
usa una interfaz
en lugar de un tipo
normalmente
cuando lo que quieres
es escribir el contrato
de un objeto
ya es más recomendable
utilizar una interfaz
en realidad funcionaría
más o menos igual
solo que las interfaces
son un poquito más fáciles
de extender
pero lo que se suele hacer
es que si es un objeto
directamente utilices una interfaz
así que ya podemos exportar aquí
este export interface
del state
ok
y ahora esto
ya aquí
en lugar de decir
que esto es initial state
le podríamos
podríamos importar
del types
el state
y fíjate
aquí puedes importar
el tipo
para que no traiga
nada de código
y aquí lo mismo
en lugar de poner
el type of no sé qué
aquí podemos poner
el state
le he puesto de nombre
state
porque vamos a tener
muy pocos
pero seguramente
tendrías que utilizar
mejores nombres
si quieres los cambias
cuando tengas el código
disponible
los cambias
y haces lo que tú quieras
es solo para que lo entiendas
vale
así que ya tenemos
tipado el estado
ahora vienen las acciones
y aquí viene una de las cosas
más interesantes
del tipado
he puesto false
en el
aquí ya está
que había puesto false
y se la había comido
como tenía el false
se la había comido con patatas
perdón
era boleano
aquí viene una de las cosas
más interesantes
con el tema de las actions
vale
y es que
aquí puedes ver
que las actions
es un poco complejo
porque cada una
tiene un tipo diferente
y cada uno
esperará un payload
diferente
claro si tú intentas
vamos a ponerlo aquí
si tú intentas
hacer export type action
y dices que la action
pues tiene
el tipo
es un string
y el payload
es any
pues esto funcionar
funcionaría
pero es una mierda
porque no nos ayuda mucho
esto en saber exactamente
que es lo que hace
funcionar
funciona
pero que pasa
que tú aquí
puedes empezar a meter
lo que te dé la gana
que no vas a detectar
cuando hay un problema
mira más fácil
imagínate que
interchange languages
me he olvidado
la s
pues no me entero
me dice
ah pues te la has comido
ya está
esto es una de las formas
malas de hacerlo
para hacer esto bien
en realidad
lo que tendrías que
hacer es
tener como
el mismo tipo
que cambie dependiendo
del tipo de acción
¿cómo haríamos esto?
pues hacemos un export type
de action
y lo que hacemos es
como concatenar
diferentes tipos
para cada uno
o sea
si el tipo
es
set from language
lo que decimos
es que el payload
tiene que ser un string
pero
si el tipo
por ejemplo
el tipo
es este de aquí
es interchange languages
pues no necesitamos
ningún payload
así que lo dejamos vacío
así lo que podríamos ver
es que ya se me queja
dice oye
el payload
no existe en el tipo action
¿por qué?
porque hay algunos
que como no lo necesitan
como por ejemplo este
como el interchange language
no tiene un payload
se nos podría quejar por esto
así que aquí lo mejor
es que solo lo utilicemos
allí donde lo tenemos
realmente tipado
pero lo bueno es que aquí
fíjate que si yo intento
utilizar aquí el action
punto payload
¿ves que se me queja?
esto es una de las magias
de TypeScript
y sobre todo
cuando trabajes con React
es que es capaz
de detectar
que si el tipo
es interchange languages
entonces
no debería tener acceso
al payload
porque no existe
cuando el tipo de acción
es interchange languages
y esto es súper potente
porque luego
lo vamos a ver
con las props
de los componentes también
y lo que te permite
es como
oye
si yo tengo este valor
lo que quiero
es que solo me permitas
hacer esto
con el contrato
de lo que me pasas
por parámetros
en este caso
ya no vamos a poder hacer esto
y ya lo tenemos
mucho mejor controlado
de hecho
tampoco podemos hacer esto
ya no nos podemos equivocar
con el string
porque como lo tenemos tipado
tampoco nos permite
oye
esta comparación
no funciona
porque solo deberías
utilizar estas dos
¿vale?
así que
esta sería una parte
de hacerlo
podríamos ir más allá
utilizar enums
para que los tipos
fuesen enums
y todo esto
luego si me da tiempo
lo hago
pero por ahora
lo vamos a dejar así
vamos con el resto de tipos
set to language
y luego
lo que sí que vamos a arreglar
es lo del payload
que sea un string
estos serían todos
creo
y el
no
el loading no lo necesitamos
¿no?
son 5 acciones
y aquí tenemos
cannot find
vale
aquí ponemos
action.payload
action.payload
vale
y action.payload
¿vale?
muy bien
pues aquí ya tendríamos
el reducer
ya lo tendríamos hecho
o sea
ya tenemos el paso 3
todo hecho
perfecto
ya tendríamos aquí
preparado tanto el estado
como el dispatch
para enviar las acciones
vamos a ver
qué más nos quedaba
aquí en nuestro escalidro
vale
esto de dual state
el dispatch
ya tenemos aquí
generar un nuevo estado
y cada vez que se renderizaba
algo nuevo
pues tenemos aquí
en el componente
o sea que aquí en el state
podríamos acceder
a cada una de estas
o sea
podríamos acceder
aquí
podríamos tener
el from language
de hecho
vamos a quitar esto
from language
to language
from text
result
y loading
¿vale?
obviamente ahora no los estamos utilizando
que ahora aquí
tendríamos todo el estado
y en el segundo
tendríamos el dispatch
¿cómo utilizaríamos el dispatch?
mira
vamos a hacer algo
vamos a poner un botón
que nos cambie
que nos cambie
por ejemplo
cambiar el loading
on click
vale
vamos a hacer esto
lo que podemos
bueno más que cambiar el loading
set from language
venga
set from language
cambiar a español
vamos a poner
cambiar a español
vale
hacemos un dispatch
y aquí lo que le decimos es
¿cuál es la acción
que queremos enviar?
bueno pues le decimos
el tipo es
y aquí
fíjate que ya tenemos
el autocomplete
porque como ya tiene
las acciones
las tiene tipadas
o sea ya sabemos
cuáles son las acciones
que queremos hacer
¿sabes?
o sea ya le hemos dicho
que estas son las acciones
entonces ya tenemos
el autocomplete aquí
que no tenemos que hacer
nada más
nos dice
oye
es que solo puedes utilizar
una de estas
no puedes utilizar
infinitas
estas son las que tienes
disponibles
pues le podemos decir
vale vamos a cambiar
el set from language
y le tenemos que pasar
también el payload
así que le pasamos
el payload
con es
si no le paso el payload
se me queja
porque ya lo tenemos
totalmente tipado
ya nos dice
no no
es que si utilizas
el set from language
tienes que pasarle el payload
esta es la gracia
justamente de TypeScript
¿vale?
esto es lo bueno
que una vez que ya
lo tenemos todo cerrado
esto ya
no nos va a dejar continuar
hasta que no lo hagamos
correctamente
vamos a poner aquí
un console log
del from language
from language
voy a activar
a ver si funciona
el console link
ah mira
si que funciona
vale veis aquí
que pone from language
auto
o sea se supone
que ahora mismo
son solo el auto
pues cuando le de
un click a este botón
al de cambiar español
que lo deberíamos tener aquí
¿ves?
cambiar español
si le doy un click
deberíamos ver
¿ves?
que ha vuelto a ejecutar
el console log
y ahora el from language
es español
o sea que ya ha hecho
esto ha hecho el dispatch
ha enviado aquí
como tenía que setear el lenguaje
ha actualizado el estado
y se ha reflejado
de hecho lo podríamos ver aquí
from language
¿vale?
si lo ponemos aquí
y lo refrescamos
¿ves?
ahora está en auto
le hacemos click
es
o sea que está haciendo esto
desde el use reducer
estamos utilizando el dispatch
luego vamos aquí
set language español
enviamos la información
del payload
que tiene ese español
va al reducer
el reducer dice
vale entiendo esta acción
con este payload
genero un nuevo estado
este estado
lo tengo aquí
y vuelvo a renderizar
el componente
con esta nueva información
¿vale?
ya habéis visto un poquito
cuál es el camino
¿no?
que hace
ok
magnífico
si
vale
perfecto
pues ahora ya
esto es con todo
todo lo del reducer
todo el rato
funciona así
y de hecho
es lo que vamos a hacer
para no hacer esto
muy rollo
en el que
tenemos esto aquí
en el mismo app
TSX
vamos a crear un custom hook
vamos a poner hooks
y vamos a poner
use store.ts
he llamado store
pero le podría llamar
como tú quieras
¿vale?
todo esto me lo voy a llevar
aquí
para que quede más limpio
el app
esto también lo vamos a importar
aquí arriba
solo que
ahora tienen que ser
dos puntitos
y en lugar de traernos
este
use reducer
aquí
lo vamos a traer
aquí
¿vale?
vamos a crear aquí
una función
export function
use store
y aquí
copiamos esto
use reducer
lo importamos aquí
ok
vamos a traernos aquí
todo el
to language
from text
result
loading
todo esto
lo vamos a devolver
return
from language
to language
from text
result
y loading
y además
vamos a crear
todas las formas
que tenemos
de actualizar el estado
¿por qué?
porque nunca vamos a querer
y esto es súper importante
no devolváis directamente
el dispatch
no hagáis
que
en vuestros componentes
tengáis los dispatch
porque eso lo que hace
es que tenéis
una
o sea
estáis atando
todos vuestros componentes
a un contrato en concreto
que es utilizar
el reducer de React
si el día de mañana
dentro de este hook
tú cambias esto
tú lo cambias
a utilizar
Zustan
a utilizar Redax
a utilizar lo que sea
no tiene por qué saberlo
el resto de componentes
¿entiendes?
o sea que es súper importante
que el dispatch
no se vea
en tus componentes
lo que tienes que hacer
en todo caso
es una mejor práctica
que es que dentro del hook
lo que hace es exportar
un contrato
que tú puedas utilizar
en cualquier sitio
y que si el día de mañana
cambia
pues que lo puedas hacer
sin ningún problema
o sea
vamos a hacer
por ejemplo
Interchange Languages
vale pues esto lo que haría
es un dispatch
del type
Interchange Languages
y tú lo que haces
es exportar esto
porque si el día de mañana
tú cambias esto
pues ya está
lo cambias
y no tiene por qué
enterarse ningún cliente
y no me refiero
cliente al usuario
sino cliente
de que esté consumiendo
este custom hook
esto es muy importante
es un error muy común
ya no en juniors
sino en gente
incluso senior
que tiene años de experiencia
y deja que los dispatch
estén a lo largo
de su aplicación
y esto no es mantenible
ni accesible
ni nada
porque es muy fácil
que intentemos
pues mantener aquí
todos nuestros dispatch
porque nadie tiene por qué
saber que estamos
utilizando el reducer
¿ok?
es un error
a muchos niveles también
que la gente
incluso le pasa
los dispatch
a métodos
funciones
de servicios
y cosas así
entonces aquí lo que vamos a hacer
es también tener
el set from language
¿vale?
todo esto
lo vamos a hacer aquí
para que nadie lo vea
¿vale?
aquí hacemos el dispatch
y el payload
se lo vamos a pasar
por aquí
payload se lo pasamos por aquí
fíjate que ahora
se nos está quejando
un montón TypeScript
ahora lo arreglaremos
primero vamos a
a poner todo esto
por aquí
set from language
el set language
también
set language
bueno
si se pone
set to
set to language
language
con el payload
esto es lo mismo
esto es muy parecido
set from text
bueno aquí
que jacopilot
nos está echando una mano
¿vale?
set result
y ya está
estos
los vamos a
set from language
set to language
set from text
set result
y ya está
ahora el problemita
que tenemos aquí
fijaos que nos dice
el payload
es any
el payload es any
vale
esto lo podríamos arreglar así
pero ahora vamos a ver
porque esto
no está bien del todo
y como lo podemos arreglar
mira vamos a arreglar esto
ahora para que no esté en rojito
y vamos a ver
porque esto no está bien del todo
y como arreglarlo
¿qué está pasando con esto?
hasta aquí
vale
ah mira
vamos a utilizar aquí el useStore
este que tenemos aquí
así que nos traemos aquí
useStore
const
y aquí traemos directamente
el
from language
from language
from language
vale
fíjate que aquí tenía un dispatch
pues ahora en lugar del dispatch
hacemos el
set from language
y es mucho mejor
porque además
no necesitamos saber el tipo
que tenemos que enviar y tal
sino que enviamos simplemente
el payload
vale
y ya está
solo tenemos que enviar el payload
mucho más fácil
si volvemos aquí
a nuestra página
y al menos le damos aquí
cambiar español
todo funciona
perfecto
pues ahora ya podemos continuar
¿qué pasa con esto?
que os estoy diciendo
que el set from language
que esto es un string
que esto no está bien
lo que está pasando aquí
es que de alguna forma
estamos como contribuyendo
a que se utilice un string
todo el rato
o sea
estamos utilizando un string
un string
esto no está bien
porque si no aquí
yo podría poner aquí
esto
y esto se lo come con patatas
y no nos está ayudando
a controlar que nuestra aplicación
realmente
no se pueda poner cualquier cosa
vamos a hacer una cosa
vamos a crear aquí
unas constantes
constants.ts
vamos a exportar
una constante
que sea
supported languages
vamos a tener
los lenguajes
que vamos a soportar
el inglés
el español
no el francés no me gusta
el francés segundo
así que
vamos a poner estos
y vamos a poner exportar también
el auto language
que en este caso
que sea auto
estos van a ser los lenguajes
que vamos a soportar
al principio
luego ya veremos
si añadimos más
pero lo bueno
de tenerlos aquí
es que los tenemos soportados
de una forma bastante
sencilla y rápida
ahora que ya tienes esto
que también lo podríamos hacer
con enums
pero a mí me gusta
intentar utilizar
el máximo javascript posible
nos vamos a volver
a los tipos
y lo que vamos a tener aquí
es un tipo
que nos diga
mira
vamos a tener un tipo
que le vamos a llamar language
y el language
es
claro
podríamos hacer esto
pero esto
no está bien del todo
porque entonces
ya tenemos
los lenguajes
en los dos sitios
aquí
y en las constantes
y esto va a ser muy difícil
que lo podamos controlar
así que lo que vamos a hacer aquí
es más bien
decirle no
el lenguaje
es una de las keys
que tenemos
en el objeto
supported languages
¿vale?
así que en esta constante
que tenemos este objeto
aquí tenemos las keys
en
es
y d
y el lenguaje
el tipo de lenguaje
solo puede ser en
es
o d
porque hemos recuperado
del tipo
de este objeto
las keys
y eso
así lo tenemos así
en lugar de ponerlo a mano
¿vale?
que mucha gente
muchas veces he visto este problema
de gente poniendo a mano
pero claro
entonces no se te
no se te sincroniza
otra forma que se podría hacer esto
es con enums
pero lo bueno que tendríamos con esto
es asegurarnos
que si el día de mañana
no queremos utilizar
TypeScript
esto funcionaría sin ningún problema
es lo más cercano a JavaScript
y utilizar esto
solo utilizamos en un sitio
o sea que ya tenemos aquí
que el lenguaje
solo puede ser
en
es
y d
también
podríamos tener lo mismo
con el
con el tipo automático
o sea
teníamos el auto language
language
¿vale?
que sería auto
directamente
o el type of
del auto language
¿vale?
y aquí
fíjate
que ya tendríamos
que esto es auto
así de fácil
lo podríamos hacer de otras formas
pero lo vamos a dejar así
¿vale?
para que entiendas sobre todo
lo del type of
que es súper potente
en TypeScript
y que te permite
no tener que repetir código
y luego
¿qué pasa?
hay aquí una cosa muy importante
y es que si miramos
Google Translate
en el from
tenemos el detectar idioma
pero en el tú
no tenemos el detectar idioma
así que
el from
vamos a tener un tipo especial
que vamos a tener
from language
donde vamos a tener
tanto language
como auto language
esta barrita de aquí
lo que sería
es como decirle
un or
o sea
estamos diciendo
o es language
o es auto language
por lo tanto
el tipo
va a ser
todos los que son language
que son estos tres
y el de auto language
es una forma
de empezar a concatenar
o expandir nuestro tipo
como combinándolos
y así
ya tenemos todo
lo que necesitamos
de tipar
de casi nuestra aplicación
o sea
ya con esto
que hemos hecho
que parece poco
ya tenemos nuestra aplicación
bastante
bastante tipada
de hecho
¿qué podemos hacer?
pues es que mira
set from language
set to language
este payload
no va a ser un string
ahora ya sabemos
que va a ser un language
así que lo podemos poner aquí
y ahora ya vemos
que es n
es
y d
lo mismo aquí
con el set from text
este sí que es un string
el result también es un string
pero el from language
ya vemos aquí
que esto debería ser
un from language
no un string
y ahora ya
lo hemos hecho
mucho más corto
n
es
d
y auto
si volvemos
a nuestra aplicación
solo con este cambio
fíjate que ahora
se me queja
cuando tú intentes hacer
un set from language
y le intentes meter aquí
el lenguaje
que te dé la gana
pues ya puedes ver
que nos está dando un problema
nos está diciendo
oye
que no puede ser
que estás intentando meter esto
y esto debería ser así
¿vale?
solo puedes meter este
este
este
pero no puedes meter
el que te dé la gana
esta es la gracia
justamente también
de tipar
que los strings
son las cadenas
o sea
el string
es el contrato
más débil
en el mundo
de la programación
sobre todo
en javascript
pero
si utilizamos
typescript
estamos como haciendo
que sean más duros
¿qué significa el key of?
el supported languages
es un objeto
¿ok?
cuando tú sacas el type of
lo que le estás diciendo
aquí en typescript
el type of
lo que está diciendo es
todo el objeto
es como copiarte
el contrato
de ese objeto
y el key of
lo que quiere decir es
de este objeto
quédate con las keys
estos son las keys
en javascript
esto es una key
esto es otra key
esto es otra key
son las llaves
del objeto
por lo que le estamos diciendo
con el key of
es que
de este contrato
de este objeto
el language
puede ser
que sea una de las keys
del type of
supported language
o sea el language
puede ser
uno de estos
de estos tres
o el n
o el s
o el d
eso es para lo que sirve
el key of
pero ten en cuenta
que el key of
no existe en javascript
¿vale?
¿qué es dispatch?
si lo quieres saber
mejor
para que lo tengas en cuenta
el dispatch
es como lanzar
entonces
es como
si tú tuvieses
un amigo
y le quisieses decir
lo que tiene que hacer
tú tienes un amigo
le dices
oye
cierra la ventana
pues el dispatch
sería
lo que estás haciendo
mandarle a tu amigo
hay veces
que a tu amigo
le puedes dar una acción
le dices
cerrar la ventana
y cerrar la ventana
no necesites
que le des nada
pero imagínate
que le dices a tu amigo
oye
dale
esta tortilla
a tu mamá
pues no solo
le vas a dar una acción
sino que le vas a dar
la información
le vas a dar
el contenido
para que lleve a cabo
esa acción
entonces no solo
tiene que llevar la tortilla
es que le tienes que dar la tortilla
para que la lleve
así que el dispatch
sería eso
mandarle a un amigo
a hacer algo
y simplemente a veces
el dispatch
no solo le tienes que decir
lo que tiene que hacer
sino que además
le tienes que añadir información
para que lo pueda hacer
venga vamos a continuar
de bootstrap
vamos a utilizar
unos cuantos componentes
para empezar a ver
algo visual
vamos a importar
el container
vamos a importar
el row
y el col
container
filas y columnas
en lugar de utilizar
este app
vamos a poner aquí
el container
le vamos a decir
que es fluido
fluido es que se ajusta
al ancho
no es que se escape
entre los dedos
luego vamos a dejar
el google translate
este por aquí
vamos a tener
si lo miráis aquí
fríamente
tendríamos
a ver
podríamos hacerlo por filas
pero yo creo que tenemos
como tres columnas
tenemos una columna
la columna está del medio
y otra columna aquí
tres columnas
vale vamos a poner
que tenemos una sola fila
tenemos tres columnas
aquí tendríamos el from
tendríamos
luego aquí la columna
del to
bueno esto no es exactamente así
y aquí tendríamos
la del icono
así que vamos a poner aquí
la del icono
aquí con el botón
button
intercambiar
ahora pondré aquí
el svg
esto así
esto lo podemos quitar
por aquí
y aquí vamos a poner
el from language
y aquí vamos a poner
el to language
y ahora utilizaremos
otro componente
de
esto
to language
ahora utilizaremos
otro componente
de bootstrap
que nos ayude
a poner el
desplegable
así que
vale ya tenemos
el from
el intercambiar
y el to
ok
bueno ahora el intercambiar
no funciona
porque no le hemos puesto
aquí el click
así que tenemos que poner
el on click
y aquí
vamos a poner
interchange
interchange languages
esto lo podríamos ejecutar
aquí tal cual
con intercambiar
vale
y fíjate
que ya empieza a funcionar
todo
hay un problemita
que vamos a arreglar
ahora antes de continuar
y es que
el auto
nunca debería ir al tú
porque en todo sentido
detectar automáticamente
donde vamos a traducir
vamos al use store
y fíjate
esta es la gracia
de los reducers
que pueden tener lógica
para evitar este tipo
de comportamiento
o sea tú lo que puedes hacer
aquí es decir
oye
si por lo que sea
el action type
vale es interchange languages
hasta aquí bien
pero
si
el estado
punto
from language
es igual a auto
pues devuelve directamente
el state
¿sabes?
o sea
no me permitas
hacer el intercambio
esto es una lógica
del estado
dentro del reducer
y es muy interesante
porque
lo evitamos
en los componentes
esto hace que esta lógica
sea súper fácil
de testear
que lo tengamos
en un sitio
que es donde tiene sentido
en lugar de lo que haría
mucha gente
que es meterlo aquí
nunca metáis aquí
la lógica
sobre todo la lógica
del estado
tiene mucho más sentido
meterlo aquí
¿vale?
así que esto es lo que vamos a hacer
vamos a evitar este cambio
¿ves?
cuando es
bueno ahora
vale
cuando el from es auto
ahora le doy click
y no funciona
esto es lo que queremos
¿vale?
justamente
de hecho
ahora es mucho más interesante
que podemos ir más allá
y decir
que si el from language
mira esto ahora
podemos decir aquí
auto language
porque lo tenemos en un
justamente en las constantes
y lo mismo aquí
aquí podríamos decir
que esto esté disabled
en el caso
de que el
el from language
sea igual
al auto language
y así incluso
visualmente
podríamos empezar
a hacer cositas
no sé si
¿ves?
ahora se ve visualmente
diferente
esto nos va a servir
luego para hacer el botón
que justo como lo tiene
google translate
si tú pones el detectar idioma
fíjate
bueno claro
es que aquí tiene cosas
vale
fíjate que
está un poco como más
más apagado
mira de hecho
vamos a hacer esto
vamos a copiar el SVG
me copio el SVG
nos vamos
voy a crear aquí
una carpeta
components
barra icons
punto tsx
export
const
arrows
icon
ponemos esto por aquí
vale
no sé si poner
una
¿sabes?
para que no quede muy grande
porque no tengo ganas
de estilarlo
arrow icons
y aquí en lugar de intercambiar
vamos a utilizar el
arrow icons
icon
vale
y este button
vamos a utilizar el botón de
bootstrap
no sé cómo será
no tengo ni idea
y al menos
vale ya tenemos esto
lo vamos a poner de tipo link
variant
link
para que no aparezca
vale
pues mira lo tenemos así
vale
y fíjate que sale como desactivado
obviamente yo creo que lo interesante
ahora que tenemos un poquito esto
es poner
lo de seleccionar el idioma
vamos a seleccionar el idioma
si miramos aquí
aquí tenemos un select
verá
que este nos va
pero perfecto
o sea es justo
justo lo que queremos
este es el que vamos a utilizar
vale
vamos a utilizar esto
para que nos quede
finito finito
vamos a crear aquí
el language
selector
punto
tsx
uy que la lío
que le he puesto de más
y hacemos un export
const
language
selector
pero fijaos
que poquito hemos hecho
todavía
o sea hemos hecho un poco
de typescript
para ver cómo se encajaba
pero todavía no hemos hecho mucho
ahora sí que haremos un poco más
porque fíjate que aquí ya se me está quejando
Beneleni
importamos el formulario
de
bootstrap
esto lo podríamos hacer así
vamos a hacerlo así
form
vale
nos traemos el formulario
tenemos que mostrar
todos los
lenguajes que soportamos
así que nos traemos
los soportes
languages
vale
por ahora vamos a dejarlo así
¿qué tenemos que hacer aquí?
bueno pues
vamos a dibujar aquí
el formulario
que seleccione
el value
por ahora no vamos a hacer nada
vamos a poner un area label
que sea selecciona
el idioma
vale
vamos a poner esto
y aquí deberíamos hacer un map
de todos los lenguajes
que soportamos
para mostrar
todas las opciones
al usuario
pues esto por acá
esto por aquí
vale
esto no es un map
exactamente
porque soporta el lenguaje
fíjate que
esto es lo bueno de typescript
me he dado cuenta
porque pensaba que no era un array
pero no es un objeto
y fíjate que el map me dice
la propiedad map
no existe en el tipo
objeto
claro
esto es un objeto
por lo tanto vamos a sacar
las entries
¿qué significa las entries?
pues que vamos a sacar
tanto la key
como el value
y lo que vamos a hacer es
que la key
y el literal
la key
es lo que va a ser
tanto la key
como el value
pero al usuario
le vamos a enseñar
el literal
y entonces
en supported languages
en las constantes
¿ves?
vamos a ver
english, spanish
incluso lo podemos poner aquí
vamos a ponerlo
english, español
y dodge
¿no?
para que sea siempre
el idioma
como oficial
que creo que es lo que hace
google translate
este language selector
ya lo podríamos empezar
a utilizar aquí
vamos a quitar esto
vamos a poner aquí
language selector
ahora mismo
pues no tiene mucha historia
aunque ya me dice
que le falta
long change
que o sea
las props
también se está quejando
es una de las mejores cosas
que te da
script con react
que te va a decir
oye
esta prop
es requerida
esto me falta esto
ahora lo arreglaremos
por ahora lo vamos a dejar así
lo que quiero es ver
pues que
realmente funciona
o sea que estamos viendo
alguna cosa por aquí
vale
pues ya tenemos aquí
el english
mira español
dodge
¿no?
lo malo
¿qué es lo que pasa?
que no estamos actualizando
el estado
si te fijas
esto sigue desactivado
y de hecho
si justo debajo
si ponemos aquí
cuál es el lenguaje
aquí
y cuál es el lenguaje aquí
aunque visualmente
vemos aquí
español
aunque yo lo cambio
¿ves?
no está cambiando el estado
le tenemos que decir nosotros
cómo cambiar el estado
o sea
le tenemos que decir
oye no
esto arreglado así
vale
pues en el on change
le vamos a pasar
que tiene que actualizar
el set
set from language
y el set to language
esto lo vamos a
llamar aquí
cuando cambia
llamamos al set from language
y cuando cambia el otro
le vamos a llamar
al set to language
¿vale?
o sea que cada uno va a cambiar
una parte del estado diferente
ahora el language selector
él no sabe
él solo recibe el on change
él no tiene ni puñetera idea
cuál es el que recibe
cuál de los dos es el correcto
por ahora una cosa
que podríamos hacer así
como en general
¿cómo tipamos las props?
a ver
primero
forma mala
bueno no forma mala no
forma
meh
sería dar
poniendo dos puntos aquí
y tiparlo así
¿no?
o sea lo que estamos haciendo
es decirle que este objeto
se tenga que tipar así
no está mal
porque como veis
ya no tenemos ningún error
esto funcionar funcionaría
pero no es la forma
que nos va a dar acceso
a las mejores posibilidades
de typescript
¿vale?
así que esta sería una
forma que está bien
la forma que ya
yo diría que empieza a estar bien
es poner una interfaz
con las props
que esté fuera
porque se va a entender
mucho mejor
que no ponerlo aquí
que es muy difícil de leer
y aquí pues empiezas a poner
por ejemplo
el on change
con el void
¿vale?
lo ponemos aquí
y aquí pues te lo puedes quitar
y solo pones
que estos son las props
¿vale?
pues esta sería otra
¿no?
ponerlo
ahí se me olvidó aquí esto
void significa nada
¿vale?
es que esto que no
es una función
que no devuelve nada
esta sería otra
¿cuál sería yo creo
la más recomendada?
seguramente
además lo bueno de esta
es que lo puedes dejar
todo en una misma línea
otra forma recomendada
que también tiene ventajas
es la de utilizar
la de react.fc
y pasarle aquí
las props
¿no?
y esto pues ya lo quitaríamos aquí
y tal
¿qué diferencia tiene?
obviamente
aquí lo que estamos haciendo es
esto es una cosa
que es de react
de hecho lo podríamos importar
de react
podríamos traer
el tipo
fc
de react
¿vale?
y este fc
lo podríamos utilizar aquí
fc
significa
function component
de hecho
si quieres la forma
function component
que es la forma larga
la puedes usar también
yo te recomiendo
utilizar la corta
porque es demasiado verboso
ya ¿vale?
¿qué es lo que está diciendo esto?
esto que ves aquí
esto es como pasarle
un parámetro
a typescript
o sea
estamos
estamos como parametrizando
el tipo
lo que le está diciendo
esto a Ria
que es
oye
este language selector
es un componente
funcional
que sus props
son
estas que tienes aquí
estamos como parametrizando
los tipos
como que le pudieras pasar
los parámetros a un tipo
para decirle cuál es el tipo
que tiene
y esto luego lo vamos a ver
porque lo vamos a usar nosotros
con el de bounce
que vamos a hacer
que está muy chulo
y es muy útil
porque claro
Ria
es incapaz de saber
antes
qué props
vas a utilizar
en tu componente
por lo tanto
se los tienes que informar tú
para eso sirve justamente
como esta de props
puedes ver un montón
de ejemplos
mucho más sencillos
por ejemplo
si tú pones numbers
si pones un, dos, tres
este numbers
si tú miras cuál es el tipo
el tipo
en realidad sería
un array
de number
¿vale?
es un array
de números
porque lo estamos nosotros
como tipando
es un array
de números
y nosotros le estamos diciendo
cuál es el tipo
números
pero podría ser de strings
y entonces tendríamos que cambiarlo
esta sería
yo creo que la más ideal
porque te trae algunas ventajas
al tener el FC
que te va a detectar
si vas a utilizar children
si no vas a utilizar children
si devuelves
por ejemplo
un string
en lugar de un elemento
un montón de cosas
pero si te gusta más la otra
por lo que sea
en la inmensa mayoría
de las ocasiones
vas a tener suficiente
pero al menos
sepáralo en una interfaz
¿vale?
es lo que te diría
necesitamos aquí
el handle change
y esto va a recibir un event
y aquí es donde vamos a llamar
al on change
pasándole el event
punto target
punto value
y este on change
lo vamos a llamar aquí
¿no?
cada vez que cambiemos
en el select
pues llamamos el on change
fíjate que ya se me queja aquí
de el parámetro
event
este
esto es un rollo
muchas veces
por cómo funciona
typescript
pero le tienes que decir
los eventos
de qué tipo son
aquí le tengo que decir
oye
esto es un evento
de react
del cambio de evento
y además
fíjate que no es suficiente
porque te dice
vale
pero el tipo value
no existe en el tipo
event target
y element
y es porque también
le tienes que informar
de qué elemento
lo estás sacando
o sea
le tenemos que decir
el cambio
el change event
es del elemento
html
select element
html select element
porque aquí
lo que estamos renderizando
es un select
y el evento
de cambio
es de este elemento
html select element
ahora este evento
sí que está
tipado correctamente
y es capaz de detectar
cada una de las propiedades
que tiene
esta sería la forma correcta
lo malo
pues que esto
lo tienes que cambiar
o sea
si es un click
si es un doble click
si es en un botón
si es en un anchor
si es no sé qué
todo eso lo tienes que tener en cuenta
para que lo estile
o sea
correctamente
vale
esto funcionar
funciona
de hecho
esto funcionar funciona
fijaos
que aquí
en el onchange
se están quejando
aquí los tipos
porque dice
oye
este onchange
parecía que todo iba bien
pero me dice
este onchange
le estás pasando aquí
debería pasarle
un from language
y aquí un language
pero tú aquí
le estás pasando un string
o sea que aquí ya espera
como mínimo
que sea language
pero fíjate
que entonces el value
me está diciendo
oye
que el value
era un string
lo estás intentando
asignar a un parámetro
del tipo
en
es
o de
aquí
le vamos a tener que forzar
a decirle
que el valor
que le estamos metiendo
en realidad es de un lenguaje
para forzar
a algún task
y le puedes decir
oye no
yo sé que
el evento
que le vas a meter
es el lenguaje
y de esta forma
ya no se va a quejar más
estamos como diciendo
esto que es un string
trátalo
como si fuese
uno de los lenguajes
que en este caso
lo tenemos controlado
porque ya sabemos
que aquí
lo único que estamos haciendo
es iterar
a través de los lenguajes
podríamos ir un poco más allá
y lo vamos a hacer
porque fíjate
que el set from language
esto pasa un from language
y aquí un set to language
solo tiene el en
es o de
o sea que hay
ligeras diferencias
entre uno y otro
o sea lo que devuelve
el on change
no es el mismo
el from language
que el set to language
porque uno tiene el auto
y el otro no
así que eso
te voy a enseñar
una cosa
muy poco utilizada
en muchos componentes
de React
pero que yo te recomiendo
que es la misma estrategia
que hemos utilizado
con el reducer
en lugar de utilizar
la interfaz
también puedes utilizar
type
no hay ningún problema
ahora estabas preguntando
a alguien
pues aquí lo que podríamos hacer
es decir
oye mira
pues vamos a tener uno
que cuando le pasemos
que el tipo es from
porque además
en el tipo from
tenemos que renderizar
también el auto
cuando le decimos
que el tipo es from
pues el valor
el value
que será un from language
¿vale?
será el tipo from language
y el on change
lo que va a recibir
es un from language
y no va a devolver luego nada
y luego tenemos
el tipo del to
que sería el de
el output
que lo que puede devolver es
o sea lo que va a recibir
es un language
o sea que no tendría el auto
no sería aceptable
recibir el auto
y cuando hacemos
un on change
solo va a poder
recibir el language
¿vale?
entonces aquí tenemos
como dos contratos
diferentes
para las mismas props
dependiendo del string
que le pasamos aquí
como type
fíjate
si tú aquí
en el language selector
que ya se me queja
¿no?
si yo le pongo
que esto es del tipo
decimos
no aquí
esto es
type
le decimos
venga type
y además te dice
si es from
pues from
entonces ya nos dice
vale
es language selector
nos dice
no es asignable
porque le falta todavía
el value
vale
pues le pasamos el value
y aquí le pasamos
el from language
¿vale?
guardamos los cambios
dice value
string
el from language
vale
en el reducer
que habíamos hecho aquí
antes habíamos dicho
que el state
fijaos
como
esto es una de las cosas
malas y buenas
de TypeScript
lo malo
es que un cambio
en la perturbación
de la fuerza
tiene una cadena
de cambios
muy bestia
claro
nosotros cuando hemos
inicializado el estado
habíamos dicho
que el from language
fíjate
que era un string
pero esto no va a ser
más así
esto es un from language
que el from language
puede ser inglés
español
alemán
o auto
el to language
pues sí que puede ser
solo language
porque no tiene auto
¿vale?
fíjate ya
que empezamos
a tener como un montón
de perturbaciones
pero esto lo que nos asegura
es que todo
lo estemos haciendo
correctamente
y bien tipado
lo mismo aquí
en las acciones
el set from language
pues aquí se le puede pasar
un from language
y el set to language
esto puede ser
un language
¿vale?
así que ahora los tipos
los tenemos bien
si volvemos en el
a nuestra aplicación
¿vale?
fíjate que ahora
aquí
ya no se me queja
mana
ahora sí que tenemos
perfectamente el contrato
de este language selector
pero
si utilizamos en este
language selector
si intentamos utilizar
por ejemplo
le decimos
el type
que sea from
que no es from
debería ser tú
y le pasamos
el value
el del tool language
fíjate
que se queja
es que es muy fino
es muy fino
porque el language selector
se queja
el language selector
se queja
que es muy difícil
de entender
porque se queja
porque
si algo malo
tiene typescript
es que
el error
los errores
son una mierda
pero lo bueno
es que
con el truco
que te voy a decir
bueno el truco
es que si sabes un poco
de typescript
ya lo deberías saber
los errores
de typescript
siempre se leen
de abajo
arriba
jamás
lo leas
de arriba abajo
porque te vas a volver loco
lo que tienes que hacer es
mira cuando me ha dado
este error typescript
digo ostras ostras
porque falla
pues vamos abajo del todo
me dice
el tipo auto
no es asignable
al tipo
inglés
español
alemán
el tipo from language
no es asignable
al tipo
inglés
español
que es lo que está pasando
si seguimos subiendo
ya vemos que
nos está indicando
que tenemos aquí
un callback
donde estamos pasando
el tipo language
lo que está pasando
es que como le hemos puesto
el type from
aquí
lo que tenemos que pasarle
es el tu
porque el tu
es el que específicamente
en el on change
solo acepta
el language
así que
aquí le decimos
que esto es tu
vale
y ahora si
funciona perfectamente
y ya tenemos
los tipos
de arriba abajo
todos
vamos
ya tenemos el tu language
que además
debería actualizar
debería actualizar
también
cuando cambiemos
ves
ahora
si que está actualizando
el estado
le podemos dar la vuelta
fijaos
ah mira aquí
no
no actualizado
no actualizado aquí
esto no
porque
ah espérate
he puesto el value aquí
no
claro
amigo
vale
es que
no estoy utilizando el value
aquí deberíamos pasar
tener tanto el type
como el value
vale
ya decía yo
pero si esto debería funcionar
vale
tenemos que pasarle al from select
el value
porque si no
no estamos controlando
lo que estamos dibujando
vale ahora si
dodge
y aquí vamos a poner español
y ahora le damos
vale
ahora si
está haciendo intercambio
para terminar
un detalle
es que
utilizando el type
vamos a decirle
oye
si el type
es igual a from
lo que podemos hacer aquí
y ahora te voy a enseñar
los enums
para que básicamente
lo puedas
ver esto correctamente
lo que vamos a hacer aquí
es que el value
sea el auto language
ahora
de esta forma
el from
va a tener
el de
detectar idioma
pero el to
no lo va a tener
ya estamos haciendo
esa pequeña diferenciación
que nos ayuda
el tipo
del input
vale
que está súper bien
porque con el mismo componente
ya estamos haciendo
tipando perfectamente
las dos cosas
y haciendo ese pequeño cambio
solo cuando lo necesitamos
habría un montón de estrategias
en este sentido
de cómo poder hacerlo
con composición y tal
pero bueno
quería hacerlo así
porque se nota
esto es una cosa
muy interesante
de las props
de poder como controlar
mejor el contrato
de las props
dependiendo del valor
de una prop en concreto
vale
que está súper chulo
para enseñar el tema
de los enums
te voy a poner un ejemplo
porque no lo he hecho
y creo que puede estar bien
vamos a utilizar un enum
para el section type
porque podemos tener
ya hemos visto
el que sea from
tendríamos el from
y el to
el enum
sería una forma
en la que podemos tener
como un objeto
como un diccionario
en el que nos vamos
a poder referir
y que va a ser constante
o sea que vamos a poder
decirle aquí
en lugar de utilizar
manualmente el string
este de type from
vamos a poder
uno
tiparlo
vamos a poder decirle aquí
en este from
vamos a decirle
section type
y vamos a decir
este
el section type
siempre
es el from
vamos a decir from
a ver si lo importa
section type
de aquí
punto
ves
ya me dice from
muchas veces
los enum
son interesantes
para evitar
tener que utilizar
strings a mano
aunque los tengas tipados
porque se leen
muchas veces
mucho mejor
y mucho más fácil
y así
fíjate que es mucho mejor
poder ahora hacer
estas comparaciones
en lugar de poner
la cadena de texto
aunque no te deja
poner otra cosa
porque esto
si pones a
se va a quejar
pero
es mucho más fácil
importar esto
y ya poner el punto
y saber lo que puedes escribir
y fíjate
que ahora ya pones esto
y ya lo tienes súper fácil
ah vale
porque lo he importado
aquí como un type
pero si lo haces así
ahora sí que funcionaría
correctamente
y este from
es from
es la cadena de texto
pero es como darle
una semántica
mucho más fácil
y además
tener como
en un solo sitio
agrupado
todo lo que serían
los enums
¿qué más?
¿qué más tendríamos?
el section type
yo creo que
¿ves aquí el type?
claro
aquí también tenemos que utilizar
el section type
section type
punto
from
y aquí section type
section type
punto
to
y así pues
podríamos empezar a utilizar
enums
como se vean mañana
¿vale?
a ver
espérate que hemos puesto
el types en algún sitio
sin la d
y no le está gustando esto
punto d
el language
punto d
debería esto
vale
fíjate ahora está desactivado
pero si cambias esto
pues activa
no se nota mucho el desactivado
pero bueno al menos
algo se nota
ahora que ya nos podemos fiar
de que el estado
se está actualizando correctamente
¿vale?
si te fijas
se está actualizando correctamente
el estado
vamos a quitar eso del estado
y vamos a quitar esto
esto del estado
y vamos a poner aquí el textarea
vamos a utilizar form punto control
de que importar el form
vamos a importar aquí el form
el formulario
form punto control
y vamos a poner como textarea
textarea
playholder
vamos a poner playholder
vale
escribe algo
escribe algo
que buena pregunta
introducir texto
introducir texto
vale
esto es en minúscula
luego vamos a poner
que esto haga autofocus
del de arriba
vamos a hacer que haga autofocus
vamos a ponerle estilos a mano
pero luego lo haremos mejor
¿vale?
hacemos estos estilos a mano
y ponemos
bueno por ahora
no es necesario el valor
esto luego lo arreglamos
¿vale?
pero por ahora
vamos a poner nuestro form
así
y este justamente debajo
solo que este
no va a tener autofocus
y además
el introducir texto este
va a ser
traducción
¿vale?
traducción
¿ok?
vamos a ver como
empieza a quedar esto
bueno
los estilos no son
lo más fuerte
el tema de las columnas
se está haciendo un poco raro
lo que podemos hacer aquí
es size
no
creo que
si se le ponía auto
auto
vale
con el auto
creo que va a pillar lo mínimo
solo lo que necesita
vale
bueno
a ver
ha pillado un poquito más
de lo que necesita
pero eso es porque hay un botón ahí
que no vemos
¿ves?
hay un botón ahí que no vemos
al menos ya
le pega un poquito más de espacio
también vamos a separar
la caja un poco
no voy a hacer los estilos
no voy a hacer los estilos
eso lo dejo a vosotros
si os queréis animar
porque me parece
mucho más interesante
utilizar ahora
la API de hecha GPT
y mostrarlo
que no ponerme con los estilos
para hacer un clon
exacto
vamos a utilizar
el componente stack
y le vamos a decir
que tenga un gap de 2
el stack al final
lo que hace es que
sería como un flex
pero ¿ves?
podemos tener ahí
nuestra separación
vamos a poner esto
como un H2
para que sea un poquito
más pequeño
Google Translate
y vamos a poner
este stack
vale
esto aquí
y este stack aquí
más que nada
para separar
vale
stack es como apilar
sería como apilar
los elementos
y lo que estamos haciendo
es que tenga una separación
de dos
ya está
vale
ya queda un poquito mejor
cuando refresquemos
fíjate que
está haciendo autofocus aquí
que es justamente
lo que queríamos
esto está bien
pero vamos a volver
a hacer la misma estrategia
de tener el mismo componente
para utilizarlo
como dos veces
para utilizarlo
tanto para
el caso de que sea
el from
como el to
vamos a utilizar
la misma estrategia
y así le vamos a cambiar
un poquito los
los estilos
vamos a mover esto
esto que habíamos hecho aquí
este form control
por ahora
lo voy a dejar ahí
pero vamos a hacer
export const
text area
y hacemos un return
por ahora de esto
con el form control
importamos
for
de
react bootstrap
¿qué necesitamos?
necesitamos
saber si está cargando
¿no?
necesitaríamos saber
si está haciendo loading
para mostrar
el texto de cargando
incluso podríamos
cambiar la opacidad
o lo que sea
también necesitamos el tipo
para saber si es el from
o el to
porque va a tener
estilos diferentes
necesitamos el valor
y necesitamos también
cuando cambie
esto es exactamente
lo mismo que hemos visto antes
vamos a tiparlo
esto lo hago un poco más rápido
porque ahora justamente
lo hemos visto
y no tiene tanto sentido
el type
pues lo mismo
section
type
vale ahora sí que lo pilla
vale
pues vamos a tener
uno y otro
pero fíjate
que esto está muy chulo
porque
lo que puedes hacer es
por ejemplo
el section type
si el section type
es from
el loading
en realidad
es opcional
porque no lo
o sea
y si viene
debería ser undefined
porque no lo necesita
el from
no muestra
en el google translate
no muestra
que esté cargando
el que lo muestra
si te fijas
es el de la derecha
podríamos ponerlo así
¿no?
¿qué más podríamos hacer?
podríamos hacer
lo del on change
que sea el value string
esto sí que puede ser exactamente igual
y el value tiene que ser un string
este es más fácil
porque no tiene un lenguaje
y no es que sea
podríamos hacerlo
al final podríamos hacer
ya veis que se parecen mucho
se parecen mucho
podríamos hacer
extenderlo
también podríamos hacer
que al final este on change
es exactamente lo mismo
el value string
podríamos extender
uno y otro
de forma que en lugar
o sea tener aquí
el common
common props
y aquí pues tener
toda esta parte
por ejemplo
que es exactamente
la misma
y solo cambiar
esto
¿sabes?
o sea
podríamos hacer algo así
y que el common props
pues sea esto
y anidar
de cada uno
tenerlo igual
podrías hacer cualquiera
de las dos cosas
o simplemente poner
que esto
tenga que ser un section type
y que esto sea
tenga que ser opcional
y ya está
solo te digo las opciones
para que las tengas
y tú decides
lo que quieras
en este caso
cuando es un objeto
ya te dice
bueno pues utiliza
un interface
lo cual me parece
que tiene sentido
pues lo vamos a dejar así
y al menos aquí
pues vamos a utilizarlo
como props
aquí
ya veremos
si no se nos queja
de que algo
venga por defecto
o lo que sea
esto vamos a poner
que sea bolean
no undefined
y ya está
el textarea
necesitamos tener
playholders diferentes
porque fíjate
que aquí
tenemos
unos introducir texto
y otros traducción
y de hecho
es como lo hemos hecho aquí
solo que en lugar
de tenerlo aquí
lo podríamos dejar aquí
la verdad
lo podríamos dejar aquí
playholder
y así te podríamos quitar
el type
ya no necesitaríamos
nada del type
ya está
entonces el playholder
se lo pasamos
y ya está
¿vale?
en lugar de ser dentro
pues lo hacemos ahí
y ya está
playholder
es un string
y aquí
ya le pasaríamos
esto lo cambiamos
por textarea
y este también
textarea
¿vale?
y ya tendríamos
el as
tampoco lo necesitamos
porque lo vamos a tener
dentro de nuestro componente
todo lo que nos podamos quitar
pues mejor
así que
aquí
este as
ya lo tenemos aquí
perfecto
¿qué más?
el autofocus
este sí que puede ser interesante
así que lo vamos a dejar aquí
autofocus
y este vamos a poner
que se ambolean
ponemos autofocus
autofocus
para indicar
cuál de los dos
es el que tiene que quitar autofocus
aunque de nuevo
esto con el tú
también lo podríamos definir
podríamos decir
si es el from
tiene autofocus
si no
o sea es que depende un poco
de la estrategia
de que las haces
lo mismo pasaría un poco
con los estilos
los estilos también
lo podemos quitar
pero
yo creo que voy a utilizar
el type
¿vale?
porque me parece interesante
porque al final
hay mucha lógica
y yo creo que tiene sentido
utilizar el type
porque
en lugar de hacer
toda la lógica
en un componente
lo tienes
o sea
en el componente padre
lo tienes en el componente hijo
que es mucho más fácil
¿sabes?
y no te lias tanto
entonces vamos a hacer
que este type
esté esto aquí
este autofocus
así autofocus
si el type
¿vale?
es igual al section
type.from
justamente esto
lo que te ayuda
es a simplificar
la lógica
que tienes en tus componentes
porque muchas veces
metes un montón de lógica
en el componente padre
y ese es donde tienes
todos los if
tienes un montón de historias
entonces esto
yo creo que puede ayudar
justamente para evitar
esta complejidad
textarea
dice que está
le falta el onChange
y el value
¿ok?
aquí vamos a tener
en el value
el fromText
vamos a ver
aquí tendríamos
el fromText
y el result
¿vale?
y el fromText
se lo vamos a pasar aquí
fromText
y aquí vamos a tener
el
value
va a ser el result
¿vale?
y nos faltaría
también el onChange
que vamos a tener aquí
el set
fromText
y el set
result
esto lo vamos a tener
en el onChange
aquí
onChange
setFromText
y onChange
setResult
ya no se queja
más TypeScript
perfecto
o sea que ya podemos
tirar aquí un poquito
vamos a cambiar
los estilos
vamos a tener aquí
commonStyles
los dos van a tener
este estilo
de 200px
vamos a poner aquí
commonStyles
pero
vamos a poner
styles
que
podríamos hacer
si el tipo
es
del
sectionType
from
hacemos uno
y si no
hacemos otro
¿vale?
vamos a cambiarle un poco
los estilos
a cada uno
como justamente
hace Google Translate
¿ves que hay uno
que no tiene borde
y el otro
tiene un fondo
y tal?
pues vamos a hacer eso
¿vale?
vamos a poner aquí
que los commonStyles
el borde es cero
no me voy a poner
a hacer todos los estilos
¿vale?
lo vamos a dejar un poco
más o menos
para que lo veas
pero bueno
esta es un poco la idea
¿vale?
es al revés
o sea esto no es aquí
esto sería aquí
y este sería el commonStyles
¿vale?
commonStyles
¿vale?
sería algo así
algo así
más o menos
el PlayHolder ahora también
se puede calcular también
en función del Type
tienes toda la razón
de hecho lo he comentado yo mismo
solo que
es verdad que no lo he hecho
al final porque
no sé por qué
pero por si lo queríamos cambiar
pero sí
tienes toda la razón
podríamos hacer que el PlayHolder
lo podríamos hacer aquí
dentro ¿vale?
o sea podríamos hacer
con PlayHolder
que si
bueno más que Loading
bueno de hecho
podríamos hacer Loading
mira
vamos a hacerlo
ya que lo has comentado
vamos a hacerlo en un momento
que además es un poquito interesante
podríamos tener fuera
del método
un GetPlayHolder
que le pasemos
el Type
el Loading
que el Type
va a ser el SectionType
el Loading va a ser un booleano
y decimos
si el Type
es
SectionType.from
como el From
le da igual
el Loading
vamos a poner
introducir texto
si estamos Loading
ponemos cargando
y si no
pues traducción
mira
con esto ya
tenemos
ah Loading
me está diciendo
que si pueda ser nul y tal
ah vale
si Loading es igual a True
así es más fácil
GetPlayHolder
GetPlayHolder
le pasamos el Type
en Loading
y mira
pim pam
nos quitamos el Value
el PlayHolder
perdón
y el Value
lo utilizamos
aquí
pasamos aquí
el Value
y quitamos
el PlayHolder
que ya no necesitamos
y aquí
ya no se nos queja
PlayHolder
y PlayHolder
cualquiera de las dos
está bien
o sea
no hay una que esté mal
y la otra que esté bien
vale
o sea
son dos estrategias
diferentes
de
hasta qué punto
tu componente
es extensible
desde fuera
hay veces
que queremos
que nuestros componentes
sean muy extensibles
por ejemplo
si son componentes
de UI
un botón
tiene que ser muy extensible
porque le tienes que pasar
cualquier texto
le tienes que pasar
cualquier color
lo que sea
pero
los componentes
cuanto más lógica
o cuanto más cerca
están del negocio
menos
menos
extensibles
tienen que ser
lo cual es muy interesante
por ejemplo aquí
puede ser que nos interese
en lugar de hacerlos
muy extensibles
hacerlos muy cerrados
de forma que
todo se controle
o no todo
sino que gran parte
se pueda controlar
desde dentro del componente
para que lo puedas
tener ahí
y lo puedas
manejar mucho mejor
que no tener
todo desperdigado
y que desde fuera
tengas que pasarle
toda esa lógica
son dos estrategias
que tienen
cada una
sentido diferente
¿de dónde sale eso
de as de antes?
a qué se refería
el as
que no culo
el as
este
esto es
qué elemento
debe renderizar
esto es de react
bootstrap
y lo que quiere decir
en este caso
es que lo que quiero renderizar
en el form control
es un text area
desactivamos el resize
es que no sé
en google translate
google translate
no tiene resize
no
no tiene resize
vale
pues desactivamos el resize
resize
ah no
no tiene
aquí no tiene
pues lo ponemos en los estilos
resize
none
pensaba que tendría
oh
resize background color
no tiene resize
como
a ver
css
resize
disable
style resize
none
porque me dice que no
inline style
setting inline styles
a ver
react inline style
resize
es raro ¿no?
debería funcionar
no sé qué historia tiene
pero el resize
mira resize both
o sea lo estoy haciendo bien
si le quito las comillas
no lo va a entender
es que tiene que ser con comillas
¿sabes?
no puede poner aquí none
porque entonces no entiende
qué es none
bueno si alguien lo encuentra
que me lo diga
porque al final
es raro
de hecho estoy bastante seguro
que va a funcionar y todo
¿veis?
que lo ha quitado
o sea eso es
tiene una pinta un poco rara
no sé si es algo
del type script
o sea de los tipos
del font control
que no le gusta
más que otra cosa
nos falta el
el on change
o sea que vamos a poner aquí
el handle change
handle change
mira
justamente aquí
change event
ahora del text area element
importante
antes habíamos utilizado el select
on change event target
¿vale?
y este handle change
lo vamos a poner aquí
on change
handle change
y esto
para que funcione
vamos a tener que ponerle
a cada uno
en el text area
vamos a poner
ya lo hemos puesto
on change
vale
perfecto
pues vamos a ver
vale
obviamente ahora no traduce nada
porque no tiene sentido
que traduzca nada
aunque sí que es verdad
que debería el loading
aparecer
ah
claro
es que fijaos que el loading
no se lo estoy pasando
aquí debería pasarle el loading
y esto debería ser
loading
tal cual
esto lo sacamos del estado
también aquí
loading
y ya está
vamos a ver
vamos a poner esto
en una línea
lo que está en una línea
vamos a poner en varias líneas
y ya está
vamos con chat GPT
a ver
como es un
es un proyecto
que queremos hacer
justamente
de react
typescript y tal
no vamos a enseñar
backend aquí
no vamos a enseñar backend
pero lo que voy a hacer
y te lo voy a explicar
80 veces
lo que voy a hacer
deberíais
pasarlo a un backend
¿vale?
hemos hecho un montón
de clases
con backend
de endpoints
y no sé qué
si queréis otro día
el viernes
lo hacemos en un momento
pero hoy me quiero enfocar
en react y typescript
entonces lo vamos a hacer
en el cliente
pero lo que vamos a hacer
no deberíais hacerlo en el cliente
porque se va a colar
vuestra API
van a robar los datos
y vuestra factura
se va a disparar
así que
disclaimer
solo que no os asustéis
de que lo hagamos en el cliente
vamos a instalar también
la API de OpenAI
la hacemos con un npm install
le decimos que la versión exacta
nada
en un momentito
vamos a instalar aquí
services
services
y vamos a poner aquí
translate
translate.ts
por ejemplo
ok
primero
de OpenAI
vamos a importar
el configuration
y el
OpenAI
API
API
¿vale?
aviso
no publiques esto
o se colará
tu API key
en el cliente
esto lo hacemos
porque nos estamos
enfocando
en este curso
en react
y typescript
debes crear
una API
para esto
o sea
todo lo que estamos haciendo
debería hacerlo la API
y nosotros atacar a la API
para que no se vea la API key
¿vale?
porque aquí
sacaríamos la API key
y en el servidor
no la veríamos
aquí lo vamos a hacer así
y ya está
bit
OpenAI
API key
¿vale?
esto vamos a ir a nuestro
vamos a crear el archivo .ef
y aquí vamos a crear
nuestra API key
dadme un momento
que voy a sacar la API key
de algún sitio
la API key
si vais a OpenAI
OpenAI
key
os cuento dos cosas
¿vale?
¿habéis cerrado todos los ojos?
mira
aquí están mis API keys
al menos
trocitos
si entráis aquí
veréis aquí
vuestras API keys
le podéis dar a crear
new secret key
¿vale?
las podéis borrar
por si os cuela
que os conozco
que muchas veces las coláis
y ya está
con esto ya lo tendréis arreglado
ahora
¿hay que pagar dinero?
sí que hay que pagar dinero
¿vale?
hay que pagar dinero
hay que pagar dinero
porque ves
cancel paid account
hay que poner
hay que poner dinero
hay que poner dinero
¿es muy caro?
pues no
a ver
de hecho yo no sé cuánto dinero llevo
mira
0,0 y 0,0
o sea
muy poco
y mira que he usado mucho
lo he usado mucho
pero si no
podéis utilizar
la DPL API
para hacer el translate
¿vale?
podéis utilizar esta
podéis utilizar
podéis utilizar
un montón de APIs
la de Coher
¿vale?
Coher API
que también está muy chula
que también podéis hacer traducciones
¿a cuánto va el kilo de tokens
de OpenAI?
si utilizáis ChatGPT
es bastante barata
ChatGPT price
bastante
bastante barata
API
es bastante barata
porque
a ver si
ChatGPT price
es 0,002
por 1000 tokens
o sea
750 palabras
o sea
son
dos
dos
no es que no son dos céntimos
es como la décima parte
de dos céntimos
por cada
750 palabras
o sea
por una
por una request
de hasta
750 palabras
o sea
o sea
está muy bien
¿el text area del tool
no dirá Star Disabled?
ah mira
buena
buena llamada
muy bien
muy interesante
muy interesante
no había caído
pero tienes toda razón
vamos a poner
que si está
si está loading
no
si es el tool
pues
muy bien
mira otra idea
de por qué
se puede utilizar esto
justamente
muy bien
buena idea
muy buena idea
tenemos que hacerlo
de la piki
oye
una cosa que me tiene
un poco mosqueado
¿por qué no?
ahora sí
¿ves que sale cargando
cuando ha empezado a escribir?
ostras
¿sabéis una cosa?
también vamos a hacer
un deferred
vamos a hacer un custom hook
con TypeScript
para hacer
para que no busque
constantemente
o sea
muy completa esta clase
vamos a seguir
ahora que ya tenemos esto
vamos con el translate
aquí
he ya sacado la api key
de openai api key
le pongo bit
porque es pública
pero ojo con esto
¿vale?
vamos a crear
la configuration
hacemos new configuration
pasándole la api key
¿vale?
vamos a crear
el cliente de openai
new openai
y le pasamos la configuración
import
supported languages
¿vale?
vamos a
porque es
creo que es lo mismo
vamos a hacer aquí
una función
asíncrona
que le damos translate
que va a recibir
tres cosas
el from language
el to language
y el text
joder que listo es
GeekhackoPilot
me cago en la leche
el from language
tiene que ser un string
to language un string
y el text un string
pues no
porque ya hemos dicho
que el from language
no va a ser un string
va a ser el from language
que puede ser auto
puede ser español
todo lo que soportamos
¿vale?
y esto es lo mismo
tiene que ser un language
aquí GeekhackoPilot
obviamente sabe mucho
pero no tanto
vale
vamos a crear
una conversación
con
con
chat GPT
con GeekhackoPilot
no
con chat GPT
le voy a decir
primero
en el rol
de
asistente
no asistente
no
system
como sistema
le vamos a decir
como se tiene que comportar
o sea
aquí le tenemos que decir
contenido
le tengo que decir
tú eres
una
IA
that
translates
text
¿vale?
¿qué vamos a hacer?
que tú recibes
you receive
a text
from
the user
no lo respondas
que es que es capaz
de responderlo
solo traslada
traduce el texto
traslada
yo también
el texto
el idioma original
está
se lo vamos a poner
surrounded by
vale
perfecto
vamos a poner así
¿vale?
que lo vamos a
a envolver
con estas comillas
y vale
vas a decir
tú también
también puedes recibir
auto
que significa
que tienes que detectar
el lenguaje
joder
que bien esto
o sea
me encanta
porque ya estamos
generando hasta el prompt
you can translate
to any language
no esto
vamos a poner
vale
the language
you translate
to
is surrounded by
tal
vale
perfecto
encima la ha cambiado
perfecto
y ahora le vamos a poner
unos ejemplos
para que funcione
correctamente
antes de ponerme
con los ejemplos
¿por qué no me
traes esto?
¿por qué no me traes esto?
vale
ahora sí
y este
define it
but never use
vale
esto ahora lo haremos
antes de seguir
con los ejemplos
muchas veces
hay muchas bibliotecas
que tienen sus propios
enums
que son muy útiles
y por ejemplo aquí
en lugar de tener
una cadena de texto
aquí que ponga
system
no sé qué
lo que puedes hacer
es utilizar
un enum
puedes decirle
chat
completion
message
request
message
enum
vale
y ahora pones
punto
esto lo tenemos
que importar
¿lo has importado?
no se ha importado
sí que se ha importado
punto
user
y con esto
deberíamos tener
el del user
debería tener más
debería estar
el del system
¿veis que aquí
ahora ha salido?
no sé por qué
no me sale
el autocomplete
en un punto
bueno no sale
autocomplete
pero está el del user
el del system
y el del assistant
venga
pues vamos ahora
role
y empieza el usuario
¿no?
dice chat
completion
request
message
from the user
el usuario te va a enviar
no
translate
no
no
esto no es así
no es así
por ejemplo
aquí pondría
hola mundo
¿vale?
y aquí
en lugar de poner aquí
el lenguaje
vamos a poner un ejemplo
nosotros
vamos a poner por ejemplo
hola mundo
esto sería spanish
esto
lo tendrías que pasar
a english
y esto
lo vamos a quitar aquí
esto lo haremos después
¿vale?
esto es lo que
te escribe el usuario
y lo que tú tienes que responder
¿vale?
el system no
el assistant
entonces diría
content
hello world
punto
¿vale?
y esto pues lo podemos hacer
unas cuantas veces
el usuario
si te dice
hola mundo
es lo mismo
vamos a poner
yo que sé
how are you
how are you
ah mira
vamos a ponerle aquí el auto
vamos a ponerle aquí el auto
no sé si poner aquí
bueno claro
es que tiene sentido
vamos a poner aquí el auto
auto
y
aquí vamos a poner
dodge
¿vale?
y entonces
el asistente que nos dice
we get this dear
vale
perfecto
vamos a poner un ejemplo más
para que no
para que no nos falle
i'm fan
thank you and you
en lugar de decir esto
vamos a poner
catalán
yo que sé
¿cómo estás?
le voy a poner auto
le vamos a poner que esto me lo pase a español
y ya está
este es el último ejemplo que le pongo
perfecto
muy bien
me parece fantástico
estos son todos los mensajes de preparación
un poco de nuestro chat GPT
from code
si el from language
es auto
entonces
le dejamos auto
si no
le vamos a poner
vamos a recuperar
si es spanish
si es dodge
y todo esto
esto de las constantes
y el to code
vamos a
recuperarlo tal cual
ahora
vamos a recuperar el completion
de llamar
a openAI
pero
en lugar de completions
que pone esto
hay que usar el create
chat completion
¿vale?
si no el otro no funciona
le decimos el modelo
el modelo vamos a utilizar
es
el de
chat GPT
pt 3.5
barra turbo
creo que es
¿lo he puesto bien?
vale
sí que lo he puesto bien
y aquí le vamos a decir
nuestros mensajes
ahora bien
nuestros mensajes
estos son como los que vamos a utilizar
de previa
y luego vamos a añadir
el nuevo del usuario
el que queremos que nos cree
le pasamos el texto
con el from
y con el to code
¿vale?
esto lo podríamos hacer
de mil millones de formas diferentes
para evitar
que nos inyecten cosas
teníamos que hacer validaciones
para evitar
que nos inyecten
cosas raras
y que se aprovechen de esto
pero
eso te lo dejo a ti
y tu creatividad
¿vale?
porque si no
nos daría aquí la vida
de hacer todas las validaciones
que necesitamos
del completion
vamos a devolver
del completion
punto
data
punto
choices
cero
pero no es text
es message
punto
content
¿vale?
vale
y fíjate que además
esto creo que le falta aquí un
esto
porque puede dar
¿vale?
y esto sería string
o undefined
con esto ya tendríamos
la respuesta
de chat GPT
a lo que le estamos pidiendo
¿podemos filtrar
que no pueda traducir
desde y hasta el mismo idioma?
sí que lo podríamos hacer aquí
claro que sí
a ver
aquí podríamos hacer
simplemente
podríamos hacer
si el front language
es el mismo
devolver el texto
y ya está
¿sabes?
pum
así de fácil
cuidado que el idioma
lo has puesto como
spanish y español
spanish
ah
bien visto
muy bien
bueno vamos a ver
cómo funciona
igual tenemos que ajustarle
un poco al prompt
puede ser
¿vale?
lo más interesante aquí
es que vamos a utilizar
un use effect
que esto ahora
lo vamos a tunear
para hacer un
deferred value
o sea
esto lo arreglaremos ahora
pero vamos a empezar con esto
vamos a hacer que cada vez
cada vez que cambie
el from text
¿vale?
vamos a hacer un console lock aquí
para ver
si se ejecuta el use effect
esto es use effect
¿vale?
ya tenemos aquí el console lock
si yo me voy
me voy aquí
me voy aquí
pam pam pam
y aquí ponemos
bla bla bla
fíjate que ya está escribiendo
ya está funcionando
o sea
cada vez
que cambio
podemos ver que cambia también
mi console lock
o sea una maravilla
una maravilla
vale
pues ahora aquí
lo que necesitaríamos
es traernos el translate
de los servicios que tenemos
simplemente
vale
vamos a mirar
que si el front text
es vacío
devolvemos
o sea no hacemos nada
pero
si sí
que
si sí que
es
o sea si sí que existe
tenemos el translate
desde el lenguaje
origen
el de destino
el texto del front text
y entonces
con esto
deberíamos tener
el set result
con el resultado
que nos devuelve
esto
podríamos
a ver
no sé si esto
claro esto nos podría dar null
si el resultado
si el resultado
es null
hacemos un return
y aquí ponemos un catch
que ponemos el result
error
yo que sé
al menos para tener el error
podríamos mejorar esto
pero al menos para tener esto
vale
argument of tabestinon
vale vale vale vale
o sea que aquí
se me está quejando
porque el result
este puede ser null
más que
dice
o sea si es null
undefined
si es null
con dos iguales
con dos iguales
con dos iguales
muchas veces
muchas veces
en javascript
no recomendamos
poner dos iguales
pero
en typescript
tiene
tiene
un uso
muy chulo
los dos iguales
que es la comparación
como laxa
no me gusta decirle
por tipos
porque no sé exactamente
por tipos
el tema
es que
tiene una comparación
bastante curiosa
no sería mejor
a ver
pero el problema
es que esto
esto
no compara lo mismo
vale
no sería mejor
no sería mejor
no sería mejor
es que no es lo mismo
no es lo mismo
no es lo mismo
de hecho fíjate
que hasta Tyskri se queja
dice
no esperaba este resultado
porque el valor condicional
no sé qué
por favor
controla esto
de mejor
vale
es que no es lo mismo
no estáis comparando
exactamente lo que queréis
porque al final
podríamos intentar también esto
vale
pero fíjate que dice
vale
un expected
new variable
string value
unconditional
no estáis comprobando lo mismo
porque entended
que un falsi
por ejemplo
el 0
sería falsi
vale
entonces lo que teníais que hacer
no es ni el uno
ni el otro
lo que tenéis que hacer aquí
es aseguraros
simplemente
que no es
ni null
ni undefined
y la mejor forma
es justamente
utilizando
el igual
igual
a null
porque esto va a comparar
si es null
o undefined
y ya sabes que aquí
seguro
tiene un string
lo cual
es una de las formas
más interesantes
de hacer este tipo de comparaciones
muy interesante
si no
también lo podríamos hacer a mano
podríamos decir
si es null
o sin result
igual
undefined
o
estará aquí
si lo hago con igual
igual
no podría ser
tendría que ser con los dos
tendría que ser así
pero si lo controláis bien
si lo hacéis
si entendéis esto
lo que hace
me parece súper bien
pues con esto
estáis haciendo la comprobación
tanto de null
como de undefined
no sé si lo sabíais
pero estaba muy chulo
con esto
a no ser que haya aquí alguna
ah vale
porque aquí hay un import
que no uso
con esto
voy a hacer una cosa
para no petarme
todos los tokens
que voy a poner aquí
a ver
de tal idioma
y voy a poner aquí
en español
voy a poner
hello world
al menos para probar
un momento
vale hello world
me lo voy a copiar
vale me encanta
porque me ha puesto
las comillas y todo
la madre que lo parió
la madre que lo parió
a ver
vamos a ponerlo
en dodge
y vamos a poner
la madre que te parió
vamos a ponerlo aquí
ah vale
I'm sorry
but the phrase you enter
is considered highly offensive
and operated to translate
como
como inteligencia artificial
me adhiero
a la ética
de los estándares morales
y no
no traduzco
contenido
que te den
que te den
la madre que te parió
como va a ser
eso ofensivo
como va a ser eso ofensivo
o sea
más
más que ofensivo
lo que tienes es
muchos bichos
traductor
a ver
vamos a decir
que más le podemos poner
que fuerte
ha detectado
el sentimiento
ha detectado
el sentimiento
a ver si esto
no le ofende
ich habe
die Stimmung
erkannt
bueno pero ya tenemos
vas a tener que hacer
un bypass
tendríamos que hacer bypass
a ver
como era
como era la frase
que me ha gustado
la madre que te parió
lo malo es
que cabrón
hostia
la madre que lo parió
mira
te lo traduce
te lo traduce
y te dice
una nota
una nota
esto es
ofensivo
es una
una frase
muy ofensiva
en español
y no te recomiendo
que la uses
que la madre
que lo trajo
Kev Kalizaya
dice
midu para evitar
conseguir muchos tokens
tendríamos que controlar
cuando el usuario
deja de escribir
o que podríamos hacer
vamos a hacer ahora
un custom hook
con typescript
parametrizable
para controlar
cuando el usuario
deja de escribir
para que se haga la búsqueda
pero bueno
a ver
funcionar funciona
y si lo pongo
en catalán
por ejemplo
bon dia
bueno
ahora me está saliendo aquí
vete a saber que
claro
es que se me vuelve loco
porque voy escribiendo
y se vuelve loco
ah
fíjate
fíjate
cuando cambio el idioma
no vuelvo a hacer la búsqueda
importante
aquí tendríamos que poner
también
el from language
para que el efecto
se ejecute
cada vez que también
cambiemos el idioma
cuando cambiamos el idioma
tiene que volver a ejecutarse
así que ahora
ves
english
good morning
touch
foot and morgan
otra cosa que veo
es que
cuando hago el set from text
vamos al use store
set from text
set from text
¿por qué el resultado
no me lo
¿sabes?
¿por qué no me lo quita?
no me lo está quitando
o sea
yo cuando digo
ah no
porque aquí estoy cambiando
el idioma
vale vale
o sea que esto del set from language
aquí también deberíamos hacer esto
y debería
claro cada
siempre que
vale vale vale
o sea deberíamos hacer esto
y tendríamos que hacer
que el loading
sería loading
si
¿cuándo está cargando?
claro
si tenemos un
from
state from text
es diferente
¿veis como de interesante
es separarlo todo
un reducer?
porque ahora
hay un montón de cosillas aquí
que podríamos empezar a cambiar
también esto
solo tiene sentido
tendríamos que evitar
si
from language
o
previous from language
o podríamos decir
si
state
punto
from language
es igual
al action payload
devolvemos
lo que ya teníamos
para evitar
que se vuelva a refrescar
cuando no tiene sentido
entonces
vamos a poner esto por aquí
y este le vamos a poner lo mismo
to language
si es igual al payload
podríamos hacer el result
y el loading
dependerá también
de si
tienen front text
y al menos así
ahora debería
¿ves?
ahora sí
ahora sí que
a esto lo arregla
¿veis?
ya tenemos un
google translate
que no está mal
no está mal
buen día
claro
puede ser que no detecte
muy bien
las que
las que no soportemos
¿no?
could you please
provide valid phrases
for me to translate?
thank you
no está mal
no está mal
el tema es que esto
no está bien
o sea
está bien
que funciona bastante bien
pero
el problema que tenemos
es que
cada vez que escribo
está intentando hacer la búsqueda
¿vale?
y se queda un poco picueto
y es un poco rollo
esto es para arreglar esto
¿veis que se ha quedado cargando
cuando he puesto vacío?
esto lo podemos arreglar
aquí en el estado
esto es lo mejor
de tener un reducer
que fijaos que
donde está la lógica del estado
es donde estamos tocando
todo lo que necesitamos
ahora mismo para arreglar
estas pequeñas cositas
por ejemplo
set front text
vale
si
lo es loading true
el loading
loading será true
si el action payload
es diferente
a un stream vacío
claro
y así
ahora
deberíamos
claro
si cambio esto
¿ves?
la traducción está bien
si pongo hola
hola
holo
necesito más contexto
para saber a lo que te quieres
bueno
eso
se le ha podido ir la olla
¿no?
porque ahora no sé
eso es porque está buscando más
o sea
he puesto una H
y ha hecho la búsqueda
y todo esto
vamos a evitar esto
¿vale?
vamos a crear un custom hook
que nos haga
un debounce
y es un custom hook
que va a ser interesante
porque lo vamos a poder parametrizar
el tipo que va a utilizar
así que vamos a crear aquí
un use the bounce
punto ts
¿qué va a necesitar esto?
export function
use the bounce
return
true
vamos a hacer un debounce
esto es una cosa que
a ver
no es para una persona
que está aprendiendo React
pero vas a ver
que es muy sencillo
de verdad
te va a sorprender
no es el mejor debounce
que vas a ver en el mundo
pero es un debounce
que es fácil de hacer
que es fácil de entender
que yo creo que cualquier persona
lo puedes seguir
y que además
lo vamos a hacer con typescript
que te puede ayudar
así que lo primero
que necesitamos
es tener un estado
¿vale?
¿por qué?
porque necesitamos un estado
donde vamos a guardar
el valor
que justamente
estamos como
detectando
si se ha cambiado
hace mucho tiempo o no
así que vamos a tener aquí
el debounced value
y un set
debounced value
si no sabes
lo que es un debounce
lo que quiere decir
es que es como
un valor
que espera un tiempo
antes de ser cambiado
¿por qué?
porque mientras yo escribo
si yo voy escribiendo aquí
va a estar disparando
todo el rato llamadas
si hago un debounce
y le digo
oye
quiero que cada 500 milisegundos
muestres
lo que
o sea
cambie el valor
entonces
tú podrás ir escribiendo
como
entre una tecla y otra
no pasa medio segundo
pues hasta que no pase
medio segundo
de la última tecla
no devolverá el nuevo valor
lo cual lo hace
mucho más interesante
el use debounce
va a recibir
el valor
el valor
que queremos observar
de si cambia
y un delay
¿vale?
un delay que además
le voy a poner
por defecto
500 milisegundos
¿ok?
bueno ya se me queja
un poquito typescript
obviamente el valor
¿qué problema tenemos
con el valor?
¿le ponemos any?
no
si le ponemos any
no se va a quejar
pero no queremos ponerle any
tampoco le ponemos
unknown
porque es verdad
que no lo sabemos
pero queremos
que el usuario
nos diga
cuál es el valor
que tiene
el valor
que quiere observar
así que le vamos a poner
una t
¿vale?
porque es como
t de type
el type
que queremos observar
no lo sabemos
pero nos lo va a decir
el usuario
¿y cómo nos lo va a decir?
pues lo vamos a hacer
con los genéricos
el use debounce
va a recibir
el tipo
por parámetro
se lo podemos pasar aquí
¿vale?
y entonces
ahora podemos utilizar
el use debounce
y decirle
no, creo que el use debounce
pues esto va a ser
de un string
o el use debounce
va a ser de lo que sea
¿vale?
lo vamos a poder decir
fíjate que si tú
intentas utilizar esto
aquí se queja
porque si le dices
que el use debounce
es de tipo number
fíjate que dice
no, el hello
es un string
no puede ser de tipo number
¿vale?
y aquí ya ves
que le estás pasando
el tipo por parámetro
es un ejemplo
muy sencillo
pero muy, muy, muy potente
el valor
es de tipo t
el tipo t
te lo pasa el usuario
por parámetro
muy bien
ahora
ya tenemos aquí
en el estado
en el estado aquí
vamos a meter
el value
aquí podríamos hacer
exactamente lo mismo
en el use state
le podríamos decir
cuál es el
el tipo que tiene
este value
que le estamos metiendo aquí
y es la t
es exactamente el mismo
aunque por suerte
seguramente aquí
ves que ya lo está
detectando automáticamente
siempre que typescript
detecte algo automáticamente
nunca le vamos a decir
nosotros el tipo
o sea
yo aquí
hacer esto
no aporta valor
porque ya lo hace
typescript automáticamente
siempre que lo infiera
te lo evitas
ahora que tenemos que hacer aquí
pues un use effect
tenemos que hacer un use effect
que vamos a tener
un timer
que miramos el timeout
con el delay
vamos a pasar aquí
el delay
y que hacemos en el delay
pues en el timeout
vamos a hacer el set
de bounce value
vamos a actualizar el valor
cada vez que pase de tiempo
el delay
cada vez que pasen
500 milisegundos
hacemos
el set state
del de bounce value
que pasa
que tú imagínate
que el value
que le pasamos
cambia
antes de que pasen
los 500 milisegundos
pues como en el efecto
vamos a limpiar
el timeout
como vamos a hacer
un clear timeout
del timer
que es lo que pasa
imagínate
0 milisegundos
usuario
user type
¿vale?
user type
100 milisegundos
¿vale?
¿qué es lo que pasa aquí?
mira, ¿qué es lo que pasa aquí?
aquí lo que pasa es que
se ejecuta el use effect
espero 500 milisegundos
a devolver
el valor
¿no?
¿qué pasa en el 150 milisegundos?
el user type
¿vale?
pues el use effect
¿qué pasa?
clear
clear
use effect
se ejecuta
la línea
mira, voy a hacerlo esto
en comentarios
para que no os hagan errores
¿vale?
pero esto es para que lo entendáis
y no tenga ningún problema
porque esto vais a escribir
un debounce
en 15 líneas de código
entonces
clear use effect
o sea, la línea 11
esto es la línea 11
use effect
esto sería la línea
línea 7
¿vale?
la línea 7
150 milisegundos
hago un clear
del use effect
o sea, la línea 11
lo limpio
por lo tanto
no seteo el valor
vuelvo a ejecutar
el use effect
línea 7
¿vale?
ahora
pasan
150 más 500
650 milisegundos
el usuario no hace nada
entonces
set the bounce value
porque han pasado 500 milisegundos
desde lo último que se había hecho
y este va a ser el nuevo valor
el nuevo valor
que vamos a tener
esto está en la línea 8
y este nuevo valor
es el que vamos a querer devolver
¿cuándo tiene que cambiar el use effect?
cada vez que cambia el value
y cuando cambiemos el delay
por si cambiamos el delay
por configuración o lo que sea
y el debounce value
es el que vamos a devolver
tan fácil como esto
ya tienes un debounce
use debounce
que hemos hecho a mano
y que se puede entender bastante bien
¿lo habéis entendido?
¿tenéis alguna pregunta?
¿alguna duda?
¿vale?
¿hay alguna duda?
pero es así
esto es un debounce
de toda la vida
lo que está pasando
es que cuando detecta
la última acción
espera el tiempo
que tú le has dicho del delay
así que
que el usuario tipea en el 0
¿vale?
ejecuto el use effect
entonces espero
el delay
que son 500 milisegundos
pero ojo
¿qué ha pasado?
el usuario
ha vuelto a cambiar
¿no?
user type
vamos a poner A
user type A
y B
¿no?
o mira
vamos a poner
H
G
¿no?
como si fuese el hello
¿no?
entonces
los 150 milisegundos
es el usuario
o sea
te tienes que pensar
el usuario
como si fuese el usuario real
estamos simulando un usuario
esto es del usuario
lo único que yo puedo controlar
es los 500 milisegundos
que espero
¿vale?
esto es como una línea del tiempo
línea del tiempo
de cómo se comporta
el usuario
¿vale?
entonces tú imagínate
que empieza el usuario
y dice
vale
lo primero que hago es
en el momento 0
escribe la H
una vez que escribe la H
llega por el value
y se ejecuta el efecto
en el setTimeout
esperamos 500 milisegundos
antes de setear el estado
¿ok?
esperamos 500 milisegundos
pero resulta que
cuando pasan 150 milisegundos
el usuario
le da la E
y dice
ostras
pues ¿qué tiene que pasar?
pues se ejecuta primero esto
limpia el efecto
y vuelve a iniciar
la espera de los 500 milisegundos
ahora
en los 300 milisegundos
el usuario
le da a la L
pues otra vez lo mismo
¿no?
volvemos a reiniciar
volvemos a reiniciar
pasan
otros 100 milisegundos
y pone gel
¿vale?
venga pues otra vez
clear effect
y tal
pero imagínate que
una vez que ha hecho esto
en este punto
el usuario para
el usuario para
¿vale?
y dice
vale
pues ya está
paro
no hay que hacer nada más
yo solo quiero traducir gel
¿vale?
¿qué es lo que va a pasar
en este punto?
que lo que vamos a hacer
es esperar
500 milisegundos
por defecto
esto lo podemos
lo podemos nosotros tunear
esperamos 500 milisegundos
como después de 500 milisegundos
no pasa nada
se ejecuta
la línea 8
¿no?
línea 8
se hace
set debounce
set debounce
set value
con gel
y
el debounce value
de la línea 14
es lo que llega
es lo que va a llegar
a nuestro componente
esto amigos
es un debounce
es un debounce
explicado muy fácil
pero súper potente
bueno total
que vamos a verlo funcionar
que es lo que queréis
vamos a ver si esto funciona
que a lo mejor no funciona
a lo mejor no funciona
use debounce
¿vale?
use debounce
ta ta ta ta ta
venga
vale
entonces
vamos a utilizar aquí
el use debounce
y le decimos
¿de qué queremos hacer el debounce?
pues lo que vamos a hacer
del from text
from text
¿vale?
debounced
text
debounce
from text
¿vale?
aquí le podríamos pasar
un delay diferente
por ejemplo 200
¿ok?
es opcional
porque ya tiene un valor
por defecto de 500
pero le vamos a poner 200
para que vaya un poquito
más rápido
250
y ahora lo interesante
es que el debounce
from text
en lugar de utilizar aquí
el from text
utilizamos el debounce
from text
¿vale?
importante
cambiamos todo el from text
por el debounce
from text
ahora que estamos aquí
pues decimos
venga
detectar idioma
vamos a poner
de
dodge
a inglés
no
es que dodge
no sé
a inglés
¿vale?
hola
bueno
ves es que yo también
he sido un poco lento
hola
¿qué tal estás?
me llamo
Miguel
ya se ha parecido
dime si no está
para lamerlo
está para meterle
un lametazo
a la pantalla
lametarlo
lametarlo
300
que igual te gana
bueno
venga pues 300
lametarlo
es el nuevo verbo
es el nuevo verbo
está muy chulo
está muy chulo
porque ahora
realmente funciona
de una forma
más parecida
¿no?
funciona
de una forma
más parecida
a Google
a ver
Google Translate
es verdad
que es bastante
rápido
¿no?
it works
in a way
more similar
to Google Translate
¿vale?
¿qué tal?
me llamo
Midu
tienes que ver
mis streams
de Twitch
para subir
de nivel
¿ves?
o sea
funciona increíble
para lametarlo
o sea
está increíble
my name is Midu
you have to check
o sea
ya está funcionando
súper bien
además cambiamos aquí
¿ves?
español
doge
cargando
¿vale?
o sea
que súper bien
dale al switch
ah
pero sí que lo ha hecho
sí que lo ha hecho
vale
vamos a arreglar el switch
el switch
funcionar funciona
funcionar funciona
pero
no se ve correctamente
¿por qué?
porque no hemos puesto
lo del logging
y tal
o sea aquí
logica de estado
si es el mismo estado
no sé qué
o sea
todo esto de loading
no sé qué
esto
esto por ejemplo
tendríamos que cambiarle
el loading
¿no?
tendríamos que poner loading
vale
loading loading
y el result
también lo tenemos que cambiar
el result tendría que ser vacío
y ahora sí
¿ves?
ahora sí que funciona
no sé por qué
ha salido un momento
el español
frontex
pero
debería funcionar
aquí es normal
que sale en español
porque
no sé qué
hace una mezcla rara
hace una mezcla rara
dodge
pero aquí sale en español
ahora
vale
aquí el english
bueno
es que esto no es english
o sea
no sé
se le debe estar
se le debe estar muriendo
pon la madre que me parió
para ver si deja de ser moralista
la madre que me parió
la madre que me parió
de mutter
de mich
jeboren hat
ojo
ya lo sabe decir
me encanta
vale
muy buena pregunta
la que dice
data riser
dice
en este caso
cuando declaras
el tipo de t
en use the bounce
vale
muy buena pregunta
y muy interesante
porque
en el use the bounce
recordáis que yo he puesto aquí la t
como para pasarle por parámetro
pero no se lo estoy pasando
si miráis aquí
el use the bounce
no se lo estoy pasando
pero es que no necesitáis pasárselo
porque fíjate
lo que hace
lo que hace typescript
yo le he dicho
el use the bounce
que recibe por parámetro
la t
pero es que
el value
también tiene la t
lo que está haciendo typescript
es inferir el tipo
porque como le estoy pasando aquí
un string
le está
está infiriendo el tipo
lo cual
es genial
pero claro
necesitamos poner la t aquí igualmente
aunque lo vaya a inferir
¿sabes?
lo necesitamos decir
que este tipo
viene inferido
viene parametrizado
es tan inteligente
que lo sabe
podríamos liarla
y poner aquí
esto es un number
y se va a quejar
ah sí
ya decía yo
digo se va a quejar
ves
dice oye
me has dicho que es un number
y esto es un string
pero esto
muchas veces
aunque lo infiere
puede ser interesante
que pongas aquí esto
porque así
te aseguras
que esto
que en un tipo
muy sencillo
como un string
no hay problema
pero si fuese un objeto
con un contrato complicado
a veces te puede ser interesante
decir vale
es que esto es
o esto es un language
y me quiero asegurar
que lo que le paso aquí
es un language
¿vale?
claro
como es un string
pues es lo suficientemente sencillo
pero hay veces que te puede interesar
¿hasta qué punto
dejarlo inferior
o dejarlo explícito?
siempre que puedas
en mi opinión
lo dejaría
lo dejaría
que lo infidiese
explícito
al final
si tú lo haces todo explícito
al final
te va a complicar mucho
la mantenibilidad
de tu código
mira
a ver
podemos hacer esto
en un momento
¿vale?
ya que me lo habéis pedido
me lo habéis pedido
con
por favor
a ver
esto también lo podríamos hacer
hello world
esto también lo podríamos hacer
de hecho
podemos hacer
por un lado
por un lado
mira
vamos a poner
español
hola mundo
y vamos a poner esto
en english
¿vale?
o inglés
mirad
vamos a hacer dos cosas
que es un momento
por ejemplo
lo de copiar
o sea lo de copiar
es easy peasy
nos vamos al icons
vamos a poner aquí
export
const
copy
o clipboard
icon
¿vale?
metemos esto por aquí
esto con más tiempo
lo podríamos hacer mejor
pero bueno
vamos
vamos a sacar
funcionalidades
sacamos funcionalidades
ah 24
o sea que es de 24
vale
venga
24
clipboard API
esto por aquí
esta
os voy a dejar ahí la explicación
por si la os interesa
¿vale?
en el app
¿qué podemos hacer aquí?
aquí podríamos tener
style
esto se tendría que hacer mejor
pero
no nos da la vida
¿vale?
así que
ponemos aquí el textarea
ponemos aquí un botón
con la variante
que sea link
con el position
absolute
ah este position
no se puede poner aquí
¿así?
se tiene que poner así
¿vale?
joder
pero si es que me lo ha hecho
ya me lo ha hecho esto
me lo ha hecho
lo ha detectado automáticamente
sabía que iba a hacer un clip
sabía que iba a hacer lo del
lo del clipboard
no me lo puedo creer
no me lo puedo creer
vale
esto por aquí
esto por acá
clipboard icon
esto lo traemos por aquí
clipboard icon
vale
y dice que esto debe ser await
a ver
esto que debe ser await
catch
vale
lo ponemos así
porque es que si no se nos queja
podemos poner aquí el handle clipboard
handle clipboard
y esto
por aquí
esto lo ponemos por aquí
handle clipboard
y ahora vamos a hacer que hable también
¿vale?
para que tenga las dos cositas
handle clipboard
handle clipboard
vale
esto por acá
y ya nuestro google translate
que es este de aquí
vale
esto no nos ha salido del todo bien
esto debería ser bottom
bottom
vale
si le damos aquí
hostia
no se que ha pasado
es como que me ha hecho otra vez el
a ver english
hostia
le ha puesto otra vez
vale
le damos click
y ahora si
ves
me ha copiado el código
me ha copiado esto de aquí
tal cual
para que ve
hostia
la madre que me parió
ah que lo he puesto en english
vale
de español a english
the mother who gave birth to me
this can be considered profanity
in some context
anda ya
cuéstate
bueno
que lo está copiando
vale
o sea que ya tenemos la funcionalidad de copiar
o sea estamos haciendo un google translate aquí entero en un momento
vamos a hacer que hable
vamos a hacer que hable
le copiamos aquí
me gustaría hacerle la opacidad y todo esto
pero obviamente
no nos da la vida
vale
vamos a poner icons
export
const
voice
icon
o volume
speaker
speaker
icon
vale
ponemos esto por aquí
claro ahora esto nos complica un poco
porque
vamos a poner otro dip aquí
que es el que va a tener estos estilos
y vamos a hacer que tenga un display
flex
display flex
ponemos aquí los dos botones
pam pam pam
y el otro botón aquí
vale
esto no sé por qué lo tiene
pero lo quitamos
esto también lo quitamos
aquí ponemos el speaker icon
el handle speak
esta hora lo arreglamos por aquí
handle speak
y vamos a poner
muy bien
es que no necesito ni mirar la documentación
lo que sí que necesitamos
en el language
este language no es tan fácil
¿no?
porque creo que necesitamos
lo que es la key
del language
punto lang
eso
return
a
47
language tag
indicating
joder pero no
no hay ni un ejemplo
que me salga
a ver
este
27
el handle
clander
handle
clander
vale
es que
¿sabéis qué pasa?
que el lenguaje que le tenemos que pasar
es muy específico
os explico un poco
esto
es algo del navegador
que tú le puedes
básicamente
decir
el texto que quieres que hable
¿vale?
es la web speech
api
esto es lo que utiliza
google
o sea
esto que veis aquí
hello world
esto es exactamente
lo mismo que vamos a utilizar
entonces
una vez que tienes la instancia
de uterance
lo que puedes es configurar
el lenguaje
lo que pasa
que el lenguaje
igual este cuela
igual este cuela
puede ser que cuele
puede ser
porque al final
el language tags
ves que tiene como
sería como el
la primera parte
que sería
el lenguaje
y luego la región
entonces tenía
en inglés
de Estados Unidos
igual
puede ser
que funcione
y automáticamente
detecte uno
pero veis que
solo en español
tenéis argentino
chileno
un montón
vamos a probarlo
a ver si cuela esto
y luego
pues le decimos que hable
y es importante
que le digáis el lenguaje
porque si no
habla un poco raro
así que
vamos en icons
en el speaker icon
este lo ponemos aquí
guardamos los cambios
ajá
esto
tenemos que ponerle
el width
que sea de 24
la altura
de 24
vale
y ya tenemos esto
bueno
no queda del todo bien
porque
la madre que me parió
no le ha gustado
me llamo
Midu
y soy
muy
bueno
comiendo sushi
que es eso
que ha sido eso
que ha sido eso
eso es muy raro
eso es muy extraño
hostia
casi me da miedo
y todo
me ha dado bastante miedo
ajá
ay dios
que miedo
que miedo
que risa
que miedo
ay
que me parto
ay que me parto
a ver
que es lo que no le gusta
esto
porque habla tan rara
la mierda esta
porque habla tan rara
no sé si es por el lang
igual es el lang
sabes igual es el lang
a ver vamos a intentar
poner un momento
solo por probar
a ver si le ponemos esto
a ver si
si deja de hablar raro
este cabrón
pero veis
habla en español
si le ponéis
por ejemplo
si le ponéis
que es
inglés
que le pasa
al inglés
gb
a ver un momento
no me lo puedo creer
es que así hablan
los americanos
tío
es que así hablan
los americanos
yo me lo puedo creer
es mentira
tío
mira mira
si pones
united states
la madre de los parios
que me parto
tío
no me lo puedo creer
no me lo puedo creer
habla todo el mundo
bien menos los americanos
tío
todo el mundo
habla bien menos los americanos
no me lo puedo creer
no me lo puedo creer
ostras
que bueno
que bueno
a ver japonés
este japonés
o es ja
no sé si es ja
o
mi nombre es midu
y estoy muy bien
a comer
mi nombre es midu
y estoy muy bien
a comer
ha visto
en en
ah pues será así
claro igual es que no tiene
mi nombre es midu
y estoy muy bien
a comer
bueno mira
que le den por saco
que se queda sin
se queda sin
a ver
lo vamos a arreglar
un momento
vamos a poner aquí
const voice
for language
vamos a poner
este no
obviamente
vamos a poner
el inglés
voy a poner
español
vamos a poner
el español neutro
español neutro
que creo que es el mexicano
se supone
dicen
dice que el español neutro
es el mexicano
está español mexicano
de eeuu
si solo
como va a haber un español
a ver esto no me lo puedo creer
español de eeuu
déjame que escuche esto
tengo que escuchar esto
porque no me lo creo
a ver español de eeuu
a ver español de eeuu
pero si es el español
de españa
es el mismo
a ver mexicano
oye pero
también la velocidad
a ver un momento
speed
se puede configurar
la velocidad
punto
on end
el pitch
el rate
yo creo que el rate
está muy
¿ves?
yo creo que está muy
mi nombre es
minu
and
y and
del meridiano
mary
hola
te atensu
vale vale
hola mundo
a ver
ahora mejor
¿no?
075
yo creo
vale vale
bueno
entonces
ahora que ya tenemos esto
vamos a poner
el mexicano
y el alemán
que esto
sí que no hay ningún problema
voice for language
y aquí vamos a poner
voice for language
el to language
y así
ya no tenemos el mismo
los problemas estos de
ponemos el hola mundo
en español
hello mundo
ah bueno
es que se hace
se hace un poco
un lío
cuando le ponen mal las cosas
hello world
ahora bien
ahora mejor
vamos a ponerlo un poquito más
hello world
vale
bueno
así puedo aprender
la pronunciación
de inglés
con mi
midutrans
bueno
con mi app
that way I can learn
English pronunciation
with my air
¿se me da sensación?
this way I can learn
English pronunciation
with my air
mejor
vale
mejor
bueno
vamos a hacerle
porque para ponerle
el rizar el rizo
y porque me parece que
para terminar esto
por todo lo alto
vamos a hacerle un pequeño test
a ver si nos va bien
y funciona correctamente
porque muchas veces
sé que no saben
ni por dónde empezar
además con TypeScript
y todo esto
vamos a hacerle un test
para asegurarnos
que funciona nuestra aplicación
correctamente
lo más interesante
de nuestra aplicación
obviamente es escribir
y ver que ha hecho
la traducción
así que
vamos
vamos
con el tema del testing
¿qué podemos hacer
con el testing?
vamos a utilizar
Vtest
porque está genial
y a mí me gusta mucho
así que vamos a instalar aquí
vamos a instalar
vamos a instalar
MPM install
el Vtest
Vtest
vamos a utilizar
Happy DOM
para que simule el DOM
vamos a utilizar
Testing Library
React
para
para que nos dé
como una serie de utilidades
para los componentes
de React
y
Testing Library
barra
User Event
para simular un usuario
para que el usuario
pues cuando hace
está tecleando
en el textarea
lo podamos simular fácilmente
instalamos estas dependencias
nos vamos a nuestro proyecto
y lo primero que ya hacemos
en el bit.confi.ts
este que tenemos por aquí
vamos a añadir aquí
test
y le ponemos
transform
le vamos a poner
environment
vale
fíjate que no tengo tipos
que se me está quejando algo
aquí una cosa que podéis hacer
es poner
la referencia
de los tipos
reference
types
no
bit.client
no
bit.test
creo que es
y ahora ya
te lo tipea correctamente
ahora si pones test
ahora tengo el autocomplete
pones test
y ahora si
podríamos poner
environment
y aquí ponemos
happy DOM
que es uno de los
que están aceptados
vale
con esto hemos configurado
ya
bit.test
para que funcione
con bit
con el environment
el entorno
que hemos dicho
para simular
el DOM
¿por qué?
porque así
pues irá más rápido
es mucho más fácil
simular un DOM
que no levantar un navegador
que es mucho más lento
pues vamos a crear
nuestro primer
bueno
nuestro primer componente
no
nuestro primer test
y
hay
he puesto TSX
vamos a poner
TTSX
no JSX
vamos a importar
el
no
el render screen
no
el describe
el hit
y el expect
de bit.test
vamos a traernos
el render
de
testing library
que vas a ver
que fácil es hacer test
y hay veces
que no queréis hacer test
por
lo que sea
porque no os apetece
pero es que vais a aprender
un momento
y es muy fácil
mira
describimos
nuestra aplicación
a ver
lo de describa
he puesto lo de describe
pero ni siquiera necesario
de hecho creo que hay uno
que se llama test
que podemos utilizar
my app
works
as expected
le podéis poner el nombre
que queráis
vale
yo voy a poner este nombre
y ya está
vamos a ver aquí
que nos dice
vale
si que tenemos que renderizar
la app
o sea que esto
hasta aquí bien
renderizamos nuestra app
pero en lugar de hacer
un render app
ahí a lo bestia
aquí vamos a traernos
nuestra app
app igual
render app
vale
que vamos a recuperar
de nuestra aplicación
lo primero
es recuperar el text area
vamos a recuperar
el text area
from
y para eso
hacemos un app
punto
get by
placeholder
por ejemplo
y utilizamos el placeholder
que le aparece
que es introducir texto
porque como es el único
que tiene eso
pues introducir texto
con esto
ya deberíamos tener
el elemento
del text area
ahora
vamos a querer también
simular que el usuario
está escribiendo
en el text area
vamos a traernos
el
a ver
from
testing library
user event
tenemos que traernos
vale
pensaba que tenía autocomplete
ah es que no
es que es default
me parece
user
user event
vale
lo primero que tenemos que hacer
con el user event
es hacer un setup
para tener el user
hacemos un user event
punto
setup
y es para inicializar
nuestro usuario
que simulamos
vale
ahora que tenemos el usuario
pues ya podemos hacer
que el user
va a escribir
en el text area
from
vamos a poner
hello world
no
porque por defecto
tenemos
detectar idioma
y lo traduce al inglés
vamos a poner
hola mundo
vale
hola mundo
¿por qué este texto?
bueno porque es bastante fácil
de saber
que la traducción
va a ser la que espero
esto
hay que tener en cuenta
que
que el usuario
escriba
es asíncrono
así que tenemos que poner
una wait
vamos a poner
que esto es una
sync await
ok
¿no es mejor obtener
por data test id?
no
y no lo digo yo
si no te fías de mi
por lo que sea
te lo voy a explicar
mira
prioridad
basado en los principios
en la guía de principios
tus test se deberían
parecer
a como interactúa
el usuario
con tu código
lo mucho
lo máximo
que se pueda
por ejemplo
primero
queries que sean accesibles
por todo el mundo
deberías intentar
hacer un get by role
get by label text
get by playholder text
que es el que he hecho yo
get by text
get by display value
get by alt text
get by title
y el último
de prioridad
está justamente
get by test id
¿se puede?
sí
pero debe ser
el último
debe ser el último
escalón
¿vale?
si no tienes otra forma
de hacerlo
pues lo haces con eso
pero si puedes
así te lo evitas
escribe el usuario
en nuestro text area
aquí puede ser
que tengamos un problema
porque estamos llamando
una API
tendría que hacer un mock
pero bueno
¿qué es lo que podemos
hacer aquí?
bueno pues
con el resultado
vamos a
vamos a
recuperar
de nuestra app
vamos a buscar
cuando haya
un display value
que incluya
el hola
¿por qué hola?
porque la traducción
bueno
puede ser hola mundo
de hecho
porque sabemos
que va
a traducirlo así
el find by display value
es buscar un elemento
que esté en pantalla
que aparezca
en un input
o un text area
un valor
que incluya este texto
claro
yo cuando estoy aquí
si buscamos
si yo pongo aquí
hola mundo
hola mundo
y lo pone en english
ya ves que pone
hello world
así que
ah bueno claro
esto tendría que ser
hello world
que he puesto
hola mundo otra vez
tiene que ser hello world
o sea
esperamos encontrar
en algún sitio
el hello world
porque lo habrá traducido
como a veces le pone un punto
lo voy a poner así
como una regex
para ver
que sea case insensitive
por si acaso
le da por ponerlo
en mayúscula
o lo que sea
y luego además
para que solo
encuentre la ocurrencia
no hace falta
que tenga puntos
sin punto y tal
y con esto
pues lo encontraré
y ya está
lo malo
puede ser
puede ser
que esto nos dé timeout
o sea
puede ser que nos dé timeout
yo voy a poner aquí
to be
trucey
vale
que el resultado
se tria o se
y si no petará
seguramente va a dar
un timeout
pero yo lo pruebo igual
poseerán moscas
en el package json
ponemos
los test
test
bitest
vale
npm run test
vamos a probar
vale
ya veis que ha fallado
por el setup
element test area
doesn't implement select
element test area
doesn't implement select
pues empezamos mal
a ver
espérate
a ver si esto
hay que ponerlo antes
claro claro
el setup hay que ponerlo
antes del render
vale
no lo puedes poner
después del render
vale
ahora no he encontrado
esto es todo lo que me renderiza
se está quejando de
oye no he encontrado
lo que me pedías
pero bueno
al menos
ves no he encontrado
con él
yo creo
seguramente
que vamos a necesitar
un timeout
otra cosa que podríamos hacer
que seguramente
mejor opción todavía
voy a ponerle 5 segundos
a ver
vale
ahora si que ha pasado
yo me imagino que es eso
que la API
a lo mejor no le da tiempo
lo mejor que podríamos hacer
en este caso
bueno
si aquí
en lugar de buscar
esto
pues no lo va a encontrar
nunca
pasarán 2 segundos
no lo encontrará
porque la traducción
no estará
esto en realidad
sería algo más parecido
a un test end to end
estamos simulando
un usuario
y estamos
incluso que se haga
la petición a la API
y ver si realmente
está funcionando correctamente
normalmente vamos a querer
hacer mocks
y con vtest
podéis hacer mocks
súper fácil
en la que podéis importar
el
podríamos importar
el translate
y hacernos pasar por él
sin ningún problema
lo hicimos el otro día
o sea que no voy a volver a hacer
porque ya lo hice
pero veis
aquí en functions
podéis
a ver si encuentro
el function
functions
aquí
podríais importarlo
moquearlo
lo hicimos una vez
la verdad
que no es difícil
así que os lo dejo
como deberes
si os queréis animar
y ahora
lo que voy a hacer
es
porque no lo he puesto
en mi dudev
aprendiendo
react
os recuerdo
que tenemos aquí
el repositorio
con todos los códigos
lo que voy a hacer
porque claro
donde lo he dejado
es un poco
de aquella manera
me voy a ir a mi proyecto
de aprendiendo
aprendiendo react
vale
y lo vamos
vamos a enviar aquí
oye esto que es
vale
esto nada
esto no es nada
esto no se para que es
pero nos traemos
todos los cambios
code punto
vale
bueno
de hecho
vamos a abrir esto
vamos a abrirlo
de otra forma
vale
a ver
os leo mientras
os leo mientras
mientras yo voy haciendo esto
os leo
a ver si os ha quedado
alguna duda
vale
esto es fácil
procedo a usar la consola
con instrucciones de memoria
y variar parámetros
precisos
no
y por qué no usar
el waveform
de testing library
el waveform
normalmente
es una mala práctica
porque siempre va a esperar
ese tiempo
en cambio
un timeout
es mucho mejor
porque va a esperar
solo el tiempo necesario
aprendiendo react
vale
vamos a quitar el desestor
de hecho
vamos a petarnos
el desestor
vamos a petarnos
el desestor
de hecho
está ahí
tío
no sé por qué
vale
una cosa importante
es que el .em
nos lo vamos a petar
de hecho
bueno
voy a hacer una cosa
con el .em
voy a quitar mi apiki
y voy a poner ahí
aquí tu apiki
para que sepas
que a ti
se pone
tu apiki
aquí
entonces
tu apiki aquí
translate
no sé qué
add new project
y ya tenemos
un proyecto más
o sea
ya van
8 o 9 casi
8 o 9 proyectos
claro
qué
es
pero
sí
esto
lo
es
c
lo
lo
c
y