Bueno, bueno compañeros...los hooks no son magia...¿Es que ha nadie se le ocurrió antes asociar una variable a una función para guardar un estado?
Y otra cosa compañeros...¿Qué me aporta tener funciones que guarden estados (al fin y al cabo siempre he podido guardar estados en variables)?
Estamos en 2020 y los hooks ya son la nueva forma de generar nuevas aplicaciones en React
¿Ya son o ya no son?
Ya son, es la forma en que se generan nuevas aplicaciones en React
de donde saca tantos pines???
Los manda a fabricar. El día que tuve el gusto de conocerlo nos dio algunos
i neeeeeeeeed
👋
/*
Para evitar estar escribiendo React.useState || React.useMemo
pueden hacer import de los hooks que necesiten.
*/importReact,{ useState, useMemo, useEffect }from'react'
Al agregar la funcionalidad de búsqueda me surgió un problema muy grande y espero ayudar a alguien mostrando lo que hice para solucionarlo. El problema era que se generaba un cuello de botella, un bucle infinito de re-renders
Puse unos cuantos console.log() para ver a qué se refería con "infinite loop", observe que cada vez que se hacía referencia a setFilteredBadges() se hacía un re-render, y esto hacía que cargara de nuevo todo, haciendo un re-render, y así demasiadas veces hasta que se rompe.
La solución es demasiado sencilla pero me tardé mucho en encontrarla jaja :(, es simplemente agregar la condición de que sólo se va a actualizar cuando haya alguna diferencia entre los resultados y los filteredBadges :)
Muchas gracias buen hombre
aleluya!
Literal los Hooks me hicieron estallar la cabeza ,tengo que mirar esta clase again, el useMemo() me recuerda a cache con Js la memo, recuerdo tomar notas del curso de Fundamentos de Java Script:
La memoización es una técnica de programación que nos permite ahorrar cómputo
// o procesamiento en JavaScript, al ir almacenando el resultado invariable de una
// función para que no sea necesario volver a ejecutar todas las instrucciones de nuevo,
// cuando se vuelva a llamar con los mismos parámetros. Es similar a usar memoria cache.
a alguien mas se le encendió el cerebro cuando metió React useMemo? :')
Search Filter
En esta clase usaremos ReactHooks, la lista en si en código esta dentro de BadgesList, el problema que tenemos para hacerlo allí es que los hooks solo sirven dentro e componentes funcionales asi que en esta caso tenemos una clase y debemos hacer ese cambio;
Para ello lo primero que haremos sera cambiar el “class” que teníamos anteriormente por function y además pasarle props como parámetro, luego eliminaremos los tris.props que teníamos en nuestro código y crearemos una constante para darle a “badges” el valor de props.badges y por ultimo eliminamos el ultimo corchete que nos sobra. Verificamos que nuestro código funcione de manera correcta y si esta todo en orden pasamos al siguiente paso.
Lo primero que hacemos es crear un form-group y colocarle la etiqueta y una barra input de texto con las clases de BootStrap. Verificamos que este todo en orden y luego procederemos a hacer que esta filter las palabras que escribamos en ella con relación a los badges creados en nuestra lista.
El primer paso sera darle un value a nuestro input al momento de escribir algo en el, asi que para ello usamos dos props, el primero es el value y el segundo es el onChange, cuando ocurra el onChange va a pasar un evento y después del evento vamos a leerlo con “console.log(e.target.value)” y de alguna forma queremos guardar el cambio efectuado por el evento en el value, asi que vamos a usar el Hook de useState, vamos hasta arriba y ;
El useState nos regresa dos valores los cuales serán el query y el setQuery “state y setState” usamos el React.useState y como valor inicial le damos el string vacio, este query es el que vamos a usar en el value y lo que sea que este en ese estado es lo que vamos a desplegar, asi que vamos a nuestra función que tenemos en onChange ;
Y en vez de console.log, le diremos setQuery al valor que tenemos en la función de onChange que tendrá por parámetro nuestro value, ya con esto tenemos nuestro value declarado, aun nos falta filtrarlo, ese es el próximo paso, para hacer eso vamos a usar la combinación de la lista de los badges y la del query;
El resultado de lo que vamos a hacer lo vamos a guardar dentro de una nueva variable a la que vaos a llamas filteredBadges y vamos a decir que sobre los badges queremos filtrarlos y a la función fiulter le pasamos una función como argumento en este caso nos va a dar cada uno de los filter y si nosotros regresamos “true” nos quedamos con el valor y si regresamos algo “false” lo descartamos, asi que los badges que queremos regresar con los que contengan lo que se esta escribiendo, es decir, lo que esta en el query.
Lo siguiente es reemplazar el uso de “badges” porque ya no tenesmoq que estar pendiente de todos los badges sino solo los que esten filtrados asi que ;
De esta manera ya podremos filtrar, pero tenemos un bug en la pagina, cuando no encontramos nada se nos va el search filter, esto pasa porque cuanbdo comenzamos a escribir, se nos filtra el valor, cambiamos la lista y esta misma llega a 0 asi que caimos en el caso de crear un new badge.
Tenemos una opcion, hacer una copia de nuestra search filter y pegarla arriba encima de no badges Found asi no perdemos nuestra barra;
if(filteredBadges.length===0){return(<div><div className="form-group"><label>FilterBadges</label><input
value={query} type="text" className="form-control" onChange={(e)=>{setQuery(e.target.value)}}/></div><h3>No badges were found</h3>
El filtro tiene ahora otro detalle y es que no nos toma las minúsculas al momento de buscar un nombre, al menos en el caso de las letras iniciales de los nombres que es la que nos interesa por lo que vamos a hacer algo que se llama normalizar, vamos a nuestro código ;
Y le colocamos el toLowerCase() para que en efectos de buscar los valores, lo hará con nuestro nombre en minúsculas y para agregar nuestro apellido al método de búsqueda, vamos a colocar los strings y encerrarlos de esta manera;
Ahora buscamos en nuestro searchFilter y veremos que funciona perfectamente excepto cuando buscamos con la letra inicial en mayuscula, pero eso es porque ovlidamos pasar nuestro Query a lowerCase;
Con esto funcionara perfecto, pero, el detalle es que nuestra lista es corta de momento pero cuando nuestra lista sea mucho mas grande, sera un cuello de botella para nuestra app para ello vamos a usar otro hook que trae React que se llama useMemo, le vamos a dar un función y unos argumentos y la primera vez que reciba ese par de argumentos va a correr la función y va a calcular el resultado y lo regresa, pero la segunda vez que tenga esos argumentos de nuevo ya tiene la contestación asi que la tiene memorizada y te la regresa rápido, asi que;
En este caso va a ser la que teníamos, ahora tenemos que regresar este valor o al menos guardarlo de alguna forma ;
const filteredBadges =React.useMemo(()=>{const result = badges.filter(badge =>{return`${badge.firstName}${badge.lastName}`.toLowerCase().includes(query.toLowerCase());})});
Y el segundo argumento de useMemo es una lista asi que vamos;
const filteredBadges =React.useMemo(()=>{const result = badges.filter(badge =>{return`${badge.firstName}${badge.lastName}`.toLowerCase().includes(query.toLowerCase());})},[ badges, query ]);
Estos son los argumentos que siempre que sean iguales la contestación si ya esta memorizada te la regresa de inmediato sino la calcula por primera vez, los argumentos que usarenis detro de ella para hacer el calculo, sera badges y el query, si el query cambia hay que volver a calcular el result, si la lista de badges cambia también hay que volverlo a calcular, cuando lleguemos a este punto el valor lo tenemos que guardar en el valor, pero el valor lo debemos guardar en algún sitio que luego se pueda usar fuera de useMemo;
const[filteredResults, setFilterRedults ]=React.useState(badges)React.useMemo(()=>{const result = badges.filter(badge =>{return`${badge.firstName}${badge.lastName}`.toLowerCase().includes(query.toLowerCase());})
Por lo que para ello vamos a crear un estado, eliminamos el filteredbadges y creamos arriba un state usando el hook useState pasando filteredResults y setFilteredResults, este hook tendra como valor inicial la lista completa de los badges, entonces cuando ya tengamos ese resultado lo tenemos que guardar;
const[query, setQuery]=React.useState('')const[filteredBadges, setFilteredBadges]=React.useState(badges)React.useMemo(()=>{const result = badges.filter(badge =>{return`${badge.firstName}${badge.lastName}`.toLowerCase().includes(query.toLowerCase());})setFilteredBadges(result)},[ badges, query ]);
Por lo que llamaremos el setFilteredBadges y le pasaremos nuestro resultado (cambiamos el result por badges en los hooks), privamos si funciona y si esta todo bien, perfecto entonces, ya la lista esta calculada asiq ue nuestra app es mucho más rápida, ahora nuestro siguiente paso sera empaquetar todo en un customHook;
Ahora encapsulamos todo en el custom Hook y retornamos el valor que sera una forma de poner el setQuery junto con el filteredBadges y regresamos el query tambien, para usar nuestro custom hook vamos a hacer lo siguiente;
Vamos a llamar nuestro custom hook de esta manera llamamos nuestra función hook con la lista de los badges como parámetro. Probamos que todo funcione perfectamente. Ahora podemos buscar una persona entre miles de ellas con nuestro search Filter, y encapsulamos toda esa lógica en una función sin que afectara nuestra interface en un solo sitio, ese custom hook ahora podemos usarlo en varios otros componentes, especialmente si son componentes que presentan una lista de invitados o de badges, ahora debemos aprender a identificar esas oportunidades donde podemos usar hooks en nuestros componentes y crear nuestros propios hooks para reducir la repetición de código y disminuir cada una de las responsabilidades que los hooks tienen.
Opino que los Hooks de react va a ser la nueva forma de programar componentes de cualquier tipo en react
Gradualmente sera una forma de trabajar, donde podamos pensar mas en hacer mas React Funcional.
Y así fue
Justo terminando el curso de React JS antes de PlatziConf Colombia 2019 😬 y... faltan 2 días 😄.
buen video, creo que debio de darle mas tiempo a este modulo
Muy bueno, estuve haciendo todo el curso con hooks! Y aunque el código es más ligero y no tenía que preocuparme por el "this", tuve que lidiar con algunso pequeños problemas, recomiendo utilizar React Hooks! Realmente es una opción increíble!
Ele me encantaría ver ese código compartido. Definitivamente usar React basándose en programación funcional de la mano de hooks es lo que mas renta hoy en día. 😄
Moví el input de filtrado a un componente para no repetir 10 líneas dos veces.
Compañero hice una solución similar pero tenia el problema que cuando se rendereaba el input por el lado de las listas y luego cuando no encontraba un badge y se rendereaba el mismo input pero para el caso que no retornaba un badge se perdia el focus. Lo solucione con autoFocus pero se debe tener cuidado ya que este en React funciona con camelcase.
Creo que mi cabeza exploto. Me siento como basura, ante su lógica de programación.
Jajaja x2
Definitivamente useMemo hace que los Hooks sean más cool todavía. No imagino lo que está por llegar
Ultimo esfuerzo...AHHHH!!
Me quedó una duda, hacer el cambio de clase a funcion, fue para aprender a usar hooks, o en este caso es necesario usar hooks?
(No sé si me explico)
Desde el sitio oficial de React dice:
"Hooks son una nueva característica en React 16.8. Estos te permiten usar el estado y otras características de React sin escribir una clase."
en esta clase muestra como pasar de forma de aprendizaje y reforzar los hoocks mas no es que sea esa la forma de hacerlo puede ser con clases.
Reitero a @masuro se define o se cambia la clase a funcion, por que la misma documentacion de react sobre los hooks lo dice:
"Los Hooks son una nueva incorporación en React 16.8. Te permiten usar estado y otras características de React sin escribir una clase."
"Pero qué es un Hook?
Hooks son funciones que te permiten “enganchar” el estado de React y el ciclo de vida desde componentes funcionales. Los hooks no funcionan dentro de las clases — te permiten usar React sin clases. (No recomendamos reescribir tus componentes existentes de la noche a la mañana, pero puedes comenzar a usar Hooks en los nuevos si quieres.)"
Ves!, dejame decirte que es un excelente curso, ya que meciona estos temas cuando hace apenas en febrero de este año los acaba de lanzar, lo cual servira muchisimo esta introducion a este tema para cuando lanzen las versiones estables en las cuales podremos usar estos features sin temor a promblemas con mantenimientos o compatibilidad entre versiones.
Saludos.
PD: este es de los mejores cursos que he toma de platzi, he aprendido demasiado, muchas gracias por la excelente forma de enseñar Sr. Doctor Profesor Richard Kaufman ;)
:En el minuto 07:35 sale mi nombre en la lista jaja que raro
Es cierto, ese es tu twitter?
Ya espero el curso profesional de hooks
Hola,
Yo realicé el mismo ejercicio pero mi componente desde el inicio era una clase, no una función, por lo que no me fue posible usar los hooks, así que realicé el ejemplo de la forma en que se haría sin usar hooks aprovechando el state y demás. Tengo 2 preguntas:
¿Qué diferencia hay entre crear componentes de clase y componentes función? ¿Hay mejora de rendimiento en alguno de los 2?
¿Cuál sería el equivalente de "useMemo" en un componente de clase?
Hola Sergio! Muy buenas preguntas por cierto.
En un inicio no deberían tener diferencia de rendimiento, esto es lo que dice Dan Abramov (Creador de Redux y un grande en el mundo de React)
“El rendimiento depende principalmente de lo que hace el código y no de si escoges una función o una clase.”
El equivalente más cercano es Aunque funciona un poco diferente pues es un Higher-Order Component de los cuales también puedes aprender más en el Curso Avanzado de React
También puedes leer más sobre las diferencias en esta entrada del blog de Dan Abramov ¿En qué se diferencian los componentes de función de las clases?
Saludos 😄