Sincronizar con Efectos
Algunos componentes tienen la necesidad de sincronizarse con sistemas externos. Por ejemplo, es posible que desees controlar un componente que no sea de React en función a un estado de React, configurar una conexión de servidor, o enviar un registro de análisis cuando un componente se muestra en la pantalla. Los Efectos te permiten ejecutar código después del renderizado para que puedas sincronizar tu componente con un sistema fuera de React.
Aprenderás
- Qué son los Efectos
- Cómo se diferencian los Efectos de los eventos
- Cómo declarar un Efecto en tu componente
- Cómo evitar que un Efecto se vuelva a ejecutar innecesariamente
- Por qué los Efectos se ejecutan dos veces en desarrollo y cómo arreglarlo
¿Qué son los efectos y en que se diferencian de los eventos?
Antes de empezar con los Efectos, necesitas familiarizarte con dos tipos de lógica dentro de los componentes de React:
-
Código renderizado (introducido en Describir la UI) se encuentra en el nivel superior de tu componente. Aquí es donde tomas las props y el estado, los modificas, y se devuelve el JSX que se desea ver en la pantalla. El código renderizado debe ser puro. Como si fuese una fórmula matemática, sólo debe calcular el resultado, y no hacer nada más.
-
controladores de eventos (introducido en Añadir interactividad) son funciones anidadas dentro de tus componentes que hacen cosas en lugar de solo calcularlas. Un controlador de evento podría actualizar un campo de un formulario, enviar una solicitud HTTP POST para comprar un producto, o hacer que el usuario navegue hacia otra pantalla. Los controladores de eventos contienen “efectos secundarios” (Pueden cambiar el estado del programa) causado por una acción específica del usuario (por ejemplo, al hacer clic en un botón o al escribir).
A veces, esto no es suficiente. Considera un componente ChatRoom que debe conectarse al servidor del chat cada vez que esté visible en pantalla. Conectarse al servidor no es un cálculo puro (es un efecto secundario), por lo que no puede suceder durante el renderizado. Sin embargo, no hay un evento particular como un clic que haga que ChatRoom se muestre en pantalla.
Los Efectos te permiten especificar efectos secundarios que son causados por el renderizado en sí mismo, en lugar de por un evento particular. Enviar un mensaje en el chat es un evento porque es directamente causado por el usuario haciendo clic en un botón. Sin embargo, establecer una conexión a un servidor es un Efecto porque debería suceder sin importar qué interacción causó que el componente apareciera. Los efectos se ejecutan al final de la confirmación, después de que la pantalla se actualice. Este es un buen momento para sincronizar los componentes de React con algún sistema externo (como una red o una biblioteca de terceros).
Quizás no necesites un Efecto
No te apresures en añadir Efectos en tus componentes. Ten en cuenta que los Efectos se usan típicamente para “salir” de tu código React y sincronizar con algún sistema externo. Esto incluye APIs del navegador, widgets de terceros, red, etc. Si tu Efecto solo ajusta un estado basado en otro estado, quizás no necesites un Efecto.
Cómo escribir un Efecto
Para escribir un Efecto, sigue los siguientes pasos:
- Declara un Efecto. Por defecto, tu Efecto se ejecutará después de cada confirmación.
- Define las dependencias del Efecto. La mayoría de los Efectos solo deben volver a ejecutarse cuando sea necesario en lugar de hacerlo después de cada renderizado. Por ejemplo, una animación de desvanecimiento solo debe desencadenarse cuando aparece el componente. La conexión y desconexión a una sala de chat solo debe suceder cuando el componente aparece y desaparece, o cuando cambia la sala de chat. Aprenderás cómo controlar esto especificando las dependencias.
- Añade limpieza si es necesario. Algunos Efectos necesitan especificar cómo detener, deshacer, o limpiar cualquier cosa que estaban haciendo. Por ejemplo, “conectar” necesita “desconectar”, “suscribirse” necesita “anular suscripción” y “buscar” necesita “cancelar” o “ignorar”. Aprenderás cómo hacer esto devolviendo una función de limpieza
Veamos cada uno de estos pasos en detalle.
Paso 1: Declara un Efecto
Para declarar un efecto en tu componente, importa el Hook useEffect desde React:
import { useEffect } from 'react';Luego, llámalo en el nivel superior de tu componente y escribe algún código dentro del Efecto:
function MyComponent() {
useEffect(() => {
// El código aquí se ejecutará después de *cada* renderizado
});
return <div />;
}Cada vez que el componente se renderiza, React actualizará la pantalla y entonces ejecutará el código dentro de useEffect. En otras palabras, useEffect “retrasa” la ejecución de una parte del código hasta que el renderizado es reflejado en la pantalla.
Veamos cómo puedes usar un Efecto para sincronizarlo con un sistema externo. Considera un componente de React <VideoPlayer>. Sería bueno controlar si está reproduciéndose o en pausa, enviándole la prop isPlaying:
<VideoPlayer isPlaying={isPlaying} />;Tu componente personalizado VideoPlayer renderiza la etiqueta incorporada en el navegador, <video>:
function VideoPlayer({ src, isPlaying }) {
// TODO: hacer algo con isPlaying
return <video src={src} />;
}Sin embargo, la etiqueta de navegador <video> no tiene la prop isPlaying. La única manera de controlarlo es la de llamar manualmente a los métodos play() y pause() en el elemento DOM. Necesitas sincronizar el valor de la prop isPlaying, que indica si el video debería estar reproduciéndose en ese momento, con llamadas como play() y pause().
Primero necesitaremos obtener una referencia al nodo de DOM <video>.
Puede que sientas la tentación de intentar llamar a play() o pause() durante el renderizado, pero eso no es correcto:
import { useState, useRef, useEffect } from 'react'; function VideoPlayer({ src, isPlaying }) { const ref = useRef(null); if (isPlaying) { ref.current.play(); // Llamar a estas funciones mientras se renderiza no está permitido. } else { ref.current.pause(); // Esto también causa error. } return