¡Bienvenida! Este es un curso especial de React Hooks

1

¿Qué aprenderás en el Curso Profesional de React Hooks?

2

¿Qué son los React Hooks y cómo cambian el desarrollo con React?

Introducción a React Hooks

3

useState: estado en componentes creados como funciones

4

useEffect: olvida el ciclo de vida, ahora piensa en efectos

5

useContext: la fusión de React Hooks y React Context

6

useReducer: como useState, pero más escalable

7

¿Qué es memoization? Programación funcional en JavaScript

8

useMemo: evita cálculos innecesarios en componentes

9

useRef: manejo profesional de inputs y formularios

10

useCallback: evita cálculos innecesarios en funciones

11

Optimización de componentes en React con React.memo

12

Custom hooks: abstracción en la lógica de tus componentes

13

Third Party Custom Hooks de Redux y React Router

Configura un entorno de desarrollo profesional

14

Proyecto: análisis y retos de Platzi Conf Store

15

Instalación de Webpack y Babel: presets, plugins y loaders

16

Configuración de Webpack 5 y webpack-dev-server

17

Configuración de Webpack 5 con loaders y estilos

18

Loaders de Webpack para Preprocesadores CSS

19

Flujo de desarrollo seguro y consistente con ESLint y Prettier

20

Git Hooks con Husky

Estructura y creación de componentes para Platzi Conf Store

21

Arquitectura de vistas y componentes con React Router DOM

22

Maquetación y estilos del home

23

Maquetación y estilos de la lista de productos

24

Maquetación y estilos del formulario de checkout

25

Maquetación y estilos de la información del usuario

26

Maquetación y estilos del flujo de pago

27

Integración de íconos y conexión con React Router

Integración de React Hooks en Platzi Conf Merch

28

Creando nuestro primer custom hook

29

Implementando useContext en Platzi Conf Merch

30

useContext en la página de checkout

31

useRef en la página de checkout

32

Integrando third party custom hooks en Platzi Conf Merch

Configura mapas y pagos con PayPal y Google Maps

33

Paso a paso para conectar tu aplicación con la API de PayPal

34

Integración de pagos con la API de PayPal

35

Completando la integración de pagos con la API de PayPal

36

Paso a paso para conectar tu aplicación con la API de Google Maps

37

Integración de Google Maps en el mapa de checkout

38

Creando un Custom Hook para Google Maps

Estrategias de deployment profesional

39

Continuous integration y continuous delivery con GitHub Actions

40

Compra del dominio y despliega con Cloudflare

Optimización de aplicaciones web con React

41

Integración de React Helmet para mejorar el SEO con meta etiquetas

42

Análisis de performance con Google Lighthouse

43

Convierte tu aplicación de React en PWA

Bonus: trabaja con Strapi CMS para crear tu propia API

44

Crea una API con Strapi CMS y consúmela con React.js

¿Qué sigue en tu carrera profesional?

45

Próximos pasos para especializarte en frontend

useMemo: evita cálculos innecesarios en componentes

8/45
Recursos

Aportes 36

Preguntas 8

Ordenar por:

Los aportes, preguntas y respuestas son vitales para aprender en comunidad. Regístrate o inicia sesión para participar.

useMemo 101
.
useMemo nos permitirá usar la memoización de forma simple, como ya vimos en la clase anterior, esto nos permite almacenar los resultados de una función para que, en caso de enviar los mismo argumentos que antes, ésta no haga los cálculos otra vez sino que devuelva el resultado que registró antes.
.
Guiándome un poco de las Documentación de React Hooks, hice un boceto de lo que sería el uso básico de useMemo:
.

.
Donde myFunction será la función que no queremos que haga los cálculos siempre, y el valueToWatch es la variable que, al cambiar de valor, hará que nuestro memo se ejecute (igual que el segundo argumento del useEffect)
.

Prework para la clase:
.
Ahora, en la clase se quiere crear una forma de búsqueda de personajes, para ello Handle:
.



.
Listo, más abajo donde hacíamos el characters.map(), cambiamos characters por filteredUsers y con eso al escribir algo en nuestro input, la lista cambiará a aquellos personajes cuyo nombre incluya el valor que le escribamos al input, pero aquí estamos haciendo el filter cada vez que cambia el valor del input (que es lo que se quiere evitar con useMemo)
.

Ahora si, el useMemo en la clase
.
Bien, queremos que se guarde el registro de resultados dependiendo de la busqueda para no ejecutar el filtrado una y otra vez, bueno, ¿Cuales serían las variables que queremos sean el trigger de nuestro memo? characters (para que se haga una vez al llamar a los characters de la API) y search (para que se ejecute cuando cambiemos nuestra búsqueda). Nuestra función ya está hecha, sería exactamente igual a lo que tenemos en filteredUsers, quedando entonces de la siguiente forma:
.

.
Y ya, con eso cada vez que escribimos en el input, useMemo revisará si esa búsqueda ya fue realizada antes o si hay que hacerla de nuevo, si ya la hizo devuelve la lista que guardo en ese entonces, si no, ejecuta la función de filter.

En la mayor parte del tiempo no deberias molestarte en optimizar re-renders inncesarios con useMemo. Usalo siempre en cuando el rendering toma una gran cantidad de tiempo como en interacciones muy altas (Graphs/Charts/Animations/etc.)

Para apreciar mejor esos cambios:

Si hacen un console.log en la función sin useMemo retorna esta cantidad de llamados al iniciar la aplicación

Por el contrarío con useMemo retorna lo siguiente al iniciar la App:

Apuntes

  • Nos ayudan a evitar cálculos innecesarios dentro de nuestros componentes, guardando los resultados en memoria de tal forma que solo se necesite realizar una solución para un problema y esa solución guardarlo en memoria, para que en una próxima ocación se acceda a este resultado

Ejemplo del hook

const filteredUsers = useMemo(
    () =>
      characters.filter((user) => {
        return user.name.toLowerCase().includes(search.toLocaleLowerCase());
      }),
    [characters, search]
  );

NOTA.- Escribe tu código para que aún funcione sin useMemo - y luego agrégalo para optimizar el rendimiento. Debido a que en el futuro, React puede elegir “olvidar” algunos valores previamente memorizados y recalcularlos en el próximo renderizado, por ejemplo para liberar memoria para componentes fuera de pantalla.

Ideas/conceptos claves

useMemo.- Devuelve un valor memorizado

Creo que hizo falta mostrar la diferencia de rendimiento entre el ejemplo con useMemo y el ejemplo sin él. También le faltó decir que no siempre hay que usarlo, que React es muy inteligente para optimizar los renderizados y darnos ejemplos de en que casos si vale la pena su uso. Buen ejemplo y explicación super clara aqui: https://youtu.be/BPB1W_rg3LQ

Realmente no explico la diferencia del uso de useMemo en el ejemplo, solo lo aplicó sin hacer comparaciones con el primer ejemplo.
No he terminado el curso pero hasta aquí la mayoría de los hooks los ha explicado muy por encima

Esta vez lo entendí mejor que el articulo previo que utilizaban calculos matemáticos para explicar useMemo

Hola Buenas la verdad no entendí mucho el uso de useMemo 😦 y pienso que a varios también les paso lo mismo. Y menos cuando vayan en la clase de useCallback. Así que aquí dejo un video de un canal de youtube donde explica los casos donde se usa useMemo de mejor manera:

https://www.youtube.com/watch?v=S8h2R71MuZU

Buscador utilizando useMemo

Si alguien dividió el Characters.jsx en componentes más pequeños sería un golazo que comentara cómo lo hizo.

Yo lo intenté pero se me hizo un lío de this y de props.

Creo que tendría que ser un componente para cada funcionalidad (Uno para la busqueda, otro para los favoritos y otro para los personajes que trae la api)

Oliver Atom: El balón es mi amigo Desarrolladores: El error es mi amigo

A menos que sea un cálculo realmente costoso debemos usar useMemo() y siemrpe dentro de una funcion pura.
Dejo recurso de ayuda: React.useMemo and when you should use it

Las clases están bien, aunque podría separarse la pantalla de characters como un componente, y que el character sea otro, al igual que la barra de busqueda. Esto es para separar la lógica y nos facilita al momento de depurar, escalar la aplicación, o cuando queramos hacer cambios en los componentes

Muy buen curso, pero tengo una pregunta en la clase anterior decia que no era buena idea hacer memo cuando llamamos a una API, si tenemos un buscador que depende de lo que le pasemos como parámetros por ejemplo https://algo.com/?name=“nombre a buscar”, en este caso al ser una API no se podría hacer lo que se hizo en esta clase?

Normalmente utilizaba la propiedad IndexOf(‘string’) !== -1 para search, pero tambien me parece bien hacerlo con include 😄

Excelente herramienta para lintear que se cumplan todas las reglas para usar hooks https://reactjs.org/docs/hooks-rules.html

Uff, ya ando pensando en varios casos de mi proyecto dónde esto quedaría genial.

Quiero compartirles mi método para poder implementar el botón de Agregar Favorito, ademas agregué la función para poder Eliminar el FavoritoÑ

const favoriteReducer = (state, action) => {
  switch (action.type) {
    case 'ADD_FAVORITE':
      return {
        ...state,
        favorites: [...state.favorites, action.payload],
      };
    case 'REMOVE_FAVORITE':
      return {
        ...state,
        favorites: state.favorites.filter(
          (character) => character.id !== action.payload
        ),
      };
    default:
      return state;
  }
};

  const handleFavorite = (character) => {
    dispatch({ type: 'ADD_FAVORITE', payload: character });
  };

  const handleUnfavorite = (character) => {
    dispatch({ type: 'REMOVE_FAVORITE', payload: character.id });
  };

Y luego es crear los botones:

          <button type='button' onClick={() => handleFavorite(character)}>
            Mark as Favorite
          </button>
          <button type='button' onClick={() => handleUnfavorite(character)}>
            Remove
          </button>

Espero les sirva y cualquier mejora es bienvenida! Un abrazo!

Quise complicarlo un poquito más, me quedo así

Todo bien pero en ningún momento demostraste la diferencia entre una función normal y una con useMemo(), bastante flojo

Comparto un video que le puede servir sobre useMemo:
https://youtu.be/THL1OPn72vo

La verdad no se si entendí bien el proposito (o la implementación) de useMemo(), pero en el ejemplo que propone el profe Oscar, en cada renderizado, se volvería a ejecutar la función que estamos tratando de memorizar debido a que en el segundo parametro le enviamos search y characters. Cada vez que cambia search, se re-renderíza el componente y a su vez, useMemo() debe volver a ejecutar la función, que es precisamente lo que estamos tratando de evitar. tiene sentido? agradecería si alguien me explica pq useMemo es adecuado aquí.

Comparto estos posts que pueden ser muy útiles cuando estén pensando si es necesario usar useMemo o useCallback (se verá mas adelante).
 
Before You memo() - Overreacted: Aquí se nos dan unos tips, como mover el estado hacia abajo o levantar el contenido, en lugar de depender del uso de useMemo cuando estamos teniendo problemas de rendimiento en nuestra aplicación.
 
When to useMemo and useCallback: Aquí se dan unos casos donde agregar useCallback o useMemo en el componente hace más lenta su ejecución por el hecho de que estas optimizaciones no son gratuitas. Se dan unos ejemplos similares al post anterior (mover el estado o el contenido) y la conclusión, que me parece demasiado valiosa, es que primero midamos y revisemos si implementar estos métodos nos dará ganancias en el performance.

Aunque es una optimización no es algo que debamos usar siempre, como vimos en la lectura pasada principalmente para funciones puras y comparto un vídeo de Miguel Ángel Duran (profesor del curso avanzado de React) sobre “useCallback y useMemo en React. ¿Los tendrías que usar SIEMPRE? ¡TE LO EXPLICO!” : https://youtu.be/duh3uKn0qnU

Referential Equality (other application of useMemo)

Taken from: https://blog.webdevsimplified.com/2020-05/memoization-in-react/

If you are unfamiliar with referential equality, it essentially defines whether the references of two values are the same. For example, {} === {} is false because it is checking referential equality. While both of the objects are empty, they reference different places in memory where the object is stored. Because of this, they are not referentially equal, and this comparison returns false.

This referential equality is important when it comes to dependency arrays, for example in useEffect.

function Component({ param1, param2 }) {
  const params = { param1, param2, param3: 5 }

  useEffect(() => {
    callApi(params)
  }, [params])
}

At first glance it may seem this useEffect works properly, but since the params object is created as a new object each render this is actually going to cause the effect to run every render since the reference of params changes each render. useMemo can fix this, though.

function Component({ param1, param2 }) {
  const params = useMemo(() => {
    return { param1, param2, param3: 5 }
  }, [param1, param2])

  useEffect(() => {
    callApi(params)
  }, [params])
}

Now if param1 and param2 do not change the params variable will be set to the cached version of params which means the reference for params will only change if param1, or param2 change. This referential equality is really useful when comparing objects in dependency arrays, but if you need to use a function in a dependency array, you can use the useCallback hook.

Some great explanation I found:

https://www.youtube.com/watch?v=THL1OPn72vo

:oooooooooooooooooooooooooooooooooooo

En este caso creo que no tiene mucho sentido usar useMemo ya que al cambiar search, siempre se realizará un nuevo cálculo, no se memorizará nada.

Si estoy equivocado corregidme.

La forma que ocupo Oscar es mucho más simple, pero en lo personal ocupe custom hook para el useMemo y me quedo así:

 //custom hook
  function useSearchCharacters(characters) {
    const [search, setSearch] = useState('');
    const [filteredcharacters, setFilteredCharacters] = useState(characters);

    useMemo(() => {
      const result = characters.filter((item) => {
        return item.name.toLowerCase().includes(search.toLowerCase());
      });

      setFilteredCharacters(result);
    }, [characters, search]);

    return { search, setSearch, filteredcharacters };
  }

y luego simplemente los traje en characters.js de esta forma:

 const { search, setSearch, filteredcharacters } = useSearchCharacters(
    characters
  );

Esta genial para hacer un custom hook del filter y poder reutilizar su logica

¿Qué tan recomendable es usar esto en temas de rendimiento si yo tuviera una app de videos?
Es decir, que por letra que vaya poniendo me vayan apareciendo los videos según el titulo, tag, nombre, etc…

Para el ejemplo del search con useMemo, me imagino que cada vez que busco, esta se guarda en useMemo?? no reemplaza las búsquedas anteriores o si?

Hola, estoy siguiendo este proyecto en Nextjs. Les dejo mi repositorio:

https://github.com/danyel117/platzi-conf-store

n