Curso react nivel medio

Introducción
useRef es un hook en React que te permite crear una referencia mutable que puede usarse para acceder directamente a un elemento DOM o almacenar un valor que persiste entre renderizaciones sin causar renderizados adicionales.


¿Qué es useRef?

  1. Referencia a elementos DOM:
    Se usa comúnmente para acceder a nodos del DOM de manera directa, como inputs o botones.

  2. Valores persistentes:
    También se puede usar para almacenar valores que no deben disparar renderizaciones cuando cambian (a diferencia de useState).


Sintaxis

1const ref = useRef(valorInicial);
  • ref.current: Contiene el valor referenciado.
  • valorInicial: Opcional, el valor inicial de la referencia.

Caso 1: Acceso a Elementos DOM

Ejemplo: Foco en un Input

1import React, { useRef } from "react";
2
3function FocoInput() {
4  const inputRef = useRef(null);
5
6  const manejarFoco = () => {
7    inputRef.current.focus(); // Enfocar el input
8  };
9
10  return (
11    <div>
12      <input type="text" ref={inputRef} placeholder="Escribe algo..." />
13      <button onClick={manejarFoco}>Enfocar Input</button>
14    </div>
15  );
16}
17
18export default FocoInput;

Explicación

  1. useRef: Crea una referencia para el input.
  2. inputRef.current: Proporciona acceso al nodo DOM del input.
  3. focus(): Enfoca el input al hacer clic en el botón.

Caso 2: Valores Persistentes entre Renderizados

useRef se puede usar para guardar valores que no deberían reiniciarse en cada render, como un contador.

Ejemplo: Contador Sin Renderizado

1import React, { useRef, useState } from "react";
2
3function ContadorConRef() {
4  const contador = useRef(0);
5  const [estado, setEstado] = useState(false); // Estado para simular un render
6
7  const incrementar = () => {
8    contador.current += 1; // Incrementar el valor
9    console.log(`Contador actual: ${contador.current}`);
10  };
11
12  return (
13    <div>
14      <p>El contador actual es: {contador.current}</p>
15      <button onClick={incrementar}>Incrementar</button>
16      <button onClick={() => setEstado(!estado)}>Forzar Renderizado</button>
17    </div>
18  );
19}
20
21export default ContadorConRef;

Explicación

  1. contador.current: Persiste su valor entre renderizados.
  2. Sin re-renderizado: Actualizar contador.current no causa que el componente se renderice.
  3. Estado adicional: El botón "Forzar Renderizado" se usa para demostrar que el valor de contador.current no se pierde.

Diferencia Entre useState y useRef

CaracterísticauseStateuseRef
Renderiza al cambiarNo
Persistencia de valoresEntre renderizadosEntre renderizados
Uso principalManejar datos que afectan la UIAcceso a nodos DOM o datos que no afectan la UI

Caso 3: Contar Renderizados

Ejemplo: Contador de Renderizados

1import React, { useRef, useEffect, useState } from "react";
2
3function ContadorDeRenderizados() {
4  const renderCount = useRef(0);
5  const [contador, setContador] = useState(0);
6
7  useEffect(() => {
8    renderCount.current += 1;
9  });
10
11  return (
12    <div>
13      <p>El componente se ha renderizado: {renderCount.current} veces</p>
14      <button onClick={() => setContador(contador + 1)}>Incrementar</button>
15    </div>
16  );
17}
18
19export default ContadorDeRenderizados;

Explicación

  1. renderCount.current: Se incrementa en cada renderización.
  2. Persistencia: El valor se mantiene entre renderizados sin afectar la UI.

Caso 4: Almacenar Valores Previos

Puedes usar useRef para guardar el valor anterior de una variable.

Ejemplo: Valor Previo

1import React, { useRef, useEffect, useState } from "react";
2
3function ValorPrevio() {
4  const [contador, setContador] = useState(0);
5  const valorPrevio = useRef(null);
6
7  useEffect(() => {
8    valorPrevio.current = contador;
9  }, [contador]);
10
11  return (
12    <div>
13      <p>Valor actual: {contador}</p>
14      <p>Valor previo: {valorPrevio.current}</p>
15      <button onClick={() => setContador(contador + 1)}>Incrementar</button>
16    </div>
17  );
18}
19
20export default ValorPrevio;

Explicación

  1. valorPrevio.current: Guarda el valor anterior de contador.
  2. useEffect: Actualiza el valor previo cada vez que contador cambia.

Caso 5: Integración con Bibliotecas Externas

Si necesitas interactuar con elementos DOM mediante bibliotecas externas (como animaciones o mapas), useRef es ideal.

Ejemplo: Animación con GSAP

1import React, { useRef, useEffect } from "react";
2import { gsap } from "gsap";
3
4function AnimacionConRef() {
5  const cajaRef = useRef(null);
6
7  useEffect(() => {
8    gsap.to(cajaRef.current, { x: 200, duration: 2 });
9  }, []);
10
11  return <div ref={cajaRef} style={cajaEstilo}>¡Muevo con GSAP!</div>;
12}
13
14const cajaEstilo = {
15  width: "100px",
16  height: "100px",
17  backgroundColor: "blue",
18  color: "white",
19  display: "flex",
20  justifyContent: "center",
21  alignItems: "center",
22};
23
24export default AnimacionConRef;

Explicación

  1. cajaRef.current: Apunta al nodo DOM.
  2. GSAP: Realiza la animación directamente en el elemento referenciado.

Consideraciones Importantes

  1. No Causa Renderizaciones:
    Actualizar un valor en useRef no actualiza la UI. Para eso, usa useState.

  2. Acceso al DOM:
    Úsalo para tareas relacionadas con nodos DOM, como enfocar inputs, medir tamaños o manejar integraciones con bibliotecas externas.

  3. Valores Persistentes:
    Ideal para guardar datos entre renderizaciones sin causar re-renderizados.


Cuándo Usar ref en Formularios en Lugar de state

En React, los formularios generalmente se manejan con estado controlado (state), lo que significa que el valor de los inputs se sincroniza con el estado del componente. Sin embargo, hay casos en los que puede ser mejor usar referencias (ref), que permiten acceder directamente al valor del DOM sin actualizar el estado.


Cuándo Usar ref en Lugar de state

Casos Comunes:

  1. Formularios simples con datos que no necesitan validación o manipulación previa:
    Si solo necesitas leer el valor una vez al enviar el formulario, ref puede ser más eficiente.

  2. Optimización del rendimiento:
    Si tienes formularios complejos con muchos campos y no quieres que cada cambio dispare una renderización, es mejor usar ref.

  3. Integración con bibliotecas externas:
    Cuando necesitas interactuar directamente con un elemento DOM, como un componente de terceros que no es compatible con React.


Ejemplo: Usando ref en un Formulario

Supongamos que tenemos un formulario que solo captura el nombre de usuario al enviarlo, pero no necesitamos que los cambios en el input disparen re-renderizaciones.

Código

1import React, { useRef } from "react";
2
3function FormularioConRef() {
4  const inputRef = useRef(null);
5
6  const manejarEnvio = (e) => {
7    e.preventDefault();
8    const valor = inputRef.current.value;
9    alert(`El nombre ingresado es: ${valor}`);
10    inputRef.current.value = ""; // Limpia el campo
11  };
12
13  return (
14    <form onSubmit={manejarEnvio}>
15      <label>
16        Nombre:
17        <input type="text" ref={inputRef} placeholder="Escribe tu nombre" />
18      </label>
19      <button type="submit">Enviar</button>
20    </form>
21  );
22}
23
24export default FormularioConRef;

Conclusión

useRef es un hook versátil que puede ser útil para:

  • Acceder y manipular elementos DOM directamente.
  • Guardar valores que persisten entre renderizados sin afectar la UI.
  • Trabajar con bibliotecas externas que requieren manipulación directa del DOM.