React useMemo y useCallback

useMemo es una función de React Hooks que te permite memorizar el resultado de un cálculo y evitar recalcularlo si los argumentos no han cambiado. Esto es útil para mejorar el rendimiento de tu aplicación, especialmente en casos en los que un cálculo puede ser costoso o el componente depende de un gran número de valores.

La función useMemo toma dos argumentos: la primera es una función que realiza el cálculo y la segunda es una matriz de dependencias. La función se ejecutará sólo si alguna de las dependencias ha cambiado desde la última vez que se ejecutó.

Aquí hay un ejemplo de un componente de React que utiliza useMemo para mejorar el rendimiento de una función que devuelve una lista de números primos:

import { useMemo } from 'react';

function isPrime(num) {
  for (let i = 2; i < num; i++) {
    if (num % i === 0) {
      return false;
    }
  }
  return num !== 1;
}

function getPrimes(count) {
  const primes = [];
  for (let i = 2; primes.length < count; i++) {
    if (isPrime(i)) {
      primes.push(i);
    }
  }
  return primes;
}

function PrimeList({ count }) {
  const primes = useMemo(() => getPrimes(count), [count]);
  return (
    <ul>
      {primes.map((prime) => (
        <li key={prime}>{prime}</li>
      ))}
    </ul>
  );
}

En este ejemplo, el componente PrimeList recibe una propiedad count y utiliza useMemo para memorizar el resultado de la función getPrimes(count). Esto significa que si count no ha cambiado, getPrimes no será llamada de nuevo y se devolverá el resultado memorizado.

useMemo es útil cuando se tiene un componente que realiza un gran número de cálculos costosos para actualizar un estado o una propiedad cada vez que se renderiza. Esto ayuda a mejorar el rendimiento de la aplicación al evitar hacer cálculos innecesarios.

useCallback es una función de React Hooks que es similar a useMemo, pero en lugar de memorizar el resultado de un cálculo, memoriza una función. La función devuelta por useCallback siempre será la misma mientras sus dependencias no cambien. Esto es útil para mejorar el rendimiento de tu aplicación cuando se utilizan funciones como controladores de eventos o funciones pasadas a componentes hijos.

La función useCallback toma dos argumentos: la primera es la función que se quiere memorizar y la segunda es una matriz de dependencias. La función se devolverá sólo si alguna de las dependencias ha cambiado desde la última vez que se devolvió.

Aquí hay un ejemplo de un componente de React que utiliza useCallback para mejorar el rendimiento de una lista de nombres:

import { useCallback } from 'react';

function NamesList({ names }) {
  const handleClick = useCallback((name) => {
    alert(`Hello, ${name}!`);
  }, []);

  return (
    <ul>
      {names.map((name) => (
        <li key={name} onClick={() => handleClick(name)}>
          {name}
        </li>
      ))}
    </ul>
  );
}

En este ejemplo, el componente NamesList recibe una propiedad names y utiliza useCallback para memorizar la función handleClick. La función recibirá un argumento con el nombre y mostrará una alerta con ese nombre cuando sea llamada. Al pasar handleClick como un controlador de evento para cada uno de los elementos de la lista

  • , se garantiza que la función no sea re-creada cada vez que se renderiza el componente.

    useCallback es útil cuando se tiene un componente que pasa funciones como propiedades a componentes hijos y se quiere asegurar de que estas funciones no son re-creadas cada vez que el componente principal se renderiza. Esto ayuda a mejorar el rendimiento de la aplicación al evitar recrear funciones innecesariamente.

    https://www.w3schools.com/react/react_usememo.asp
    https://www.w3schools.com/react/react_usecallback.asp
    https://beta.reactjs.org/reference/react/useMemo
    https://developero.io/blog/react-hook-usememo

    https://beta.reactjs.org/reference/react/useCallback
    https://latteandcode.medium.com/el-hook-usecallback-y-react-memo-87f761733c35

  • React useReducer

    useReducer es una función de React Hooks que te permite manejar el estado de tu aplicación de manera similar a como lo harías con un reducer en una aplicación Redux. A diferencia de useState, que sólo te permite guardar y actualizar un único valor de estado, useReducer te permite manejar estado complejo y encapsular la lógica relacionada con ese estado en un solo lugar.

    useReducer toma dos argumentos: el primer argumento es una función reducer y el segundo argumento es el estado inicial. La función reducer toma el estado actual y una acción, y devuelve el nuevo estado. El estado inicial es el valor inicial que se usará cuando se monta el componente.

    Aquí hay un ejemplo de un componente de React que utiliza useReducer para manejar el estado de un contador:

    import { useReducer } from 'react';
    
    function reducer(state, action) {
      switch (action.type) {
        case 'increment':
          return { count: state.count + 1 };
        case 'decrement':
          return { count: state.count - 1 };
        default:
          throw new Error();
      }
    }
    
    function Counter() {
      const [state, dispatch] = useReducer(reducer, { count: 0 });
    
      return (
        <>
          <h1>{state.count}</h1>
          <button onClick={() => dispatch({ type: 'increment' })}>+</button>
          <button onClick={() => dispatch({ type: 'decrement' })}>-</button>
        </>
      );
    }
    

    En este ejemplo, el componente Counter utiliza la función useReducer para inicializar el estado con un objeto { count: 0 }. Luego, el componente utiliza unos botones para incrementar o decrementar el contador. Cada vez que el usuario hace clic en un botón, el componente llama a dispatch con una acción específica, que es manejada por el reducer para actualizar el estado. El estado actualizado es entonces pasado al componente para renderizar.

    Al igual que useState, useReducer devuelve un par de valores, el estado actual y una función dispatch para actualizarlo. Al tener toda la lógica relacionada con el estado en un solo lugar, es más fácil entender cómo se actualiza el estado y resolver cualquier problema relacionado con eso.

    useReducer es útil en aplicaciones de React de mayor tamaño y complejidad, ya que te permite manejar estado complejo y encapsular la lógica relacionada con este.

    https://www.w3schools.com/react/react_usereducer.asp
    https://beta.reactjs.org/reference/react/useReducer
    https://ewebik.com/react-js/usereducer
    https://developero.medium.com/react-hooks-usereducer-4d7b68ce22e2
    https://devtrium.com/posts/how-to-use-react-usereducer-hook

    React useref

    useRef es una función de React Hooks que te permite crear una referencia a un elemento del DOM en un componente de React. Una referencia es simplemente una forma de guardar una referencia al elemento del DOM en una variable, para que puedas acceder y manipularlo más tarde.

    Por ejemplo, puedes usar useRef para guardar una referencia a un elemento de entrada de texto y luego utilizar esa referencia para limpiar el valor de ese campo después de que el usuario haya enviado un formulario:

    import { useRef } from 'react';
    
    function Form() {
      const inputRef = useRef(null);
    
      function handleSubmit(event) {
        event.preventDefault();
        inputRef.current.value = '';
      }
    
      return (
        <form onSubmit={handleSubmit}>
          <input ref={inputRef} type="text" />
          <button type="submit">Submit</button>
        </form>
      );
    }
    
    

    En este ejemplo, se crea una referencia a inputRef utilizando useRef y se le pasa null como valor inicial. Luego se asigna esta referencia al elemento de entrada <input> mediante la propiedad ref. Al enviar el formulario, el evento onSubmit activa una función manejadora en la que se accede al valor actual de inputRef.current y se limpia.

    useRef también es útil si necesitas guardar una referencia a un objeto o una función en un componente de React, en lugar de un elemento del DOM. Por ejemplo, puedes guardar una referencia a una instancia de una clase o a un objeto de configuración, y luego acceder a él desde diferentes lugares en tu componente.

    https://latteandcode.medium.com/react-el-hook-useref-6e20f026d5b
    https://keepcoding.io/blog/para-que-sirven-las-refs-en-react/
    https://keepcoding.io/blog/useref-en-react/
    https://beta.reactjs.org/reference/react/useRef

    Ejercicio CRUD

    Vamos a crear un mantenimiento de una BD de alumnos:

    {
      "alumno": [
        {
          "id": 1,
          "nombre": "Ana Pi",
          "email": "ana@pi.com",
          "nota": 8
        },
        {
          "id": 2,
          "nombre": "Eva Buj",
          "email": "eva@buj.com",
          "nota": 7
        },
        {
          "id": 3,
          "nombre": "Juan Ra",
          "email": "juan@ra.com",
          "nota": 4
        }
      ]
    }
    

    La haremos como hemos estado haciendo los CRUD de C# de MVC, una lista de alumnos con botones de editar y borrar y un botón de añadir nuevo.