Curso react nivel medio
Introducción
React.lazy es una función que permite cargar componentes de manera diferida, es decir, solo cuando se necesitan. Esto es especialmente útil para optimizar el rendimiento de tu aplicación al dividir el código (code splitting) y evitar cargar toda la aplicación de una sola vez.
¿Qué es React.lazy?
React.lazy se usa para cargar componentes dinámicamente en lugar de incluirlos en el paquete inicial. Esto es útil cuando tienes componentes grandes o que no se usan inmediatamente (como rutas o modales).
Sintaxis de React.lazy
1const MiComponente = React.lazy(() => import('./MiComponente'));
React.lazy: Importa el componente de manera diferida.import('./MiComponente'): Devuelve una promesa que React utiliza para cargar el componente dinámicamente.
Nota: Debes usar React.Suspense como envoltorio para manejar el estado de carga mientras el componente se descarga.
Ejemplo Básico: Carga Diferida de un Componente
Paso 1: Crear el Componente
Crea un componente grande o de carga diferida, por ejemplo: ComponentePesado.js.
1import React from "react"; 2 3function ComponentePesado() { 4 return <h1>Este componente fue cargado de manera diferida</h1>; 5} 6 7export default ComponentePesado;
Paso 2: Usar React.lazy
En el archivo principal, carga el componente de manera diferida.
1import React, { Suspense, useState } from "react"; 2 3// Importación diferida del componente 4const ComponentePesado = React.lazy(() => import("./ComponentePesado")); 5 6function App() { 7 const [mostrar, setMostrar] = useState(false); 8 9 return ( 10 <div> 11 <h1>Ejemplo con React.lazy</h1> 12 <button onClick={() => setMostrar(!mostrar)}> 13 {mostrar ? "Ocultar" : "Mostrar"} Componente Pesado 14 </button> 15 <Suspense fallback={<p>Cargando...</p>}> 16 {mostrar && <ComponentePesado />} 17 </Suspense> 18 </div> 19 ); 20} 21 22export default App;
Explicación
React.lazy: Carga el componente solo cuando es necesario (ComponentePesado).Suspense: Muestra un contenido de carga (<p>Cargando...</p>) mientras el componente se descarga.- Estado (
useState): Controlamos cuándo mostrar el componente diferido.
Lazy Loading en Rutas con react-router-dom
Un caso común es cargar componentes diferidos en las rutas de la aplicación.
Ejemplo
1import React, { Suspense } from "react"; 2import { BrowserRouter as Router, Route, Routes } from "react-router-dom"; 3 4// Carga diferida de componentes 5const Home = React.lazy(() => import("./Home")); 6const About = React.lazy(() => import("./About")); 7 8function App() { 9 return ( 10 <Router> 11 <Suspense fallback={<p>Cargando...</p>}> 12 <Routes> 13 <Route path="/" element={<Home />} /> 14 <Route path="/about" element={<About />} /> 15 </Routes> 16 </Suspense> 17 </Router> 18 ); 19} 20 21export default App;
Explicación
React.lazy: Cada ruta (HomeyAbout) se carga solo cuando se visita.Suspense: Muestra un indicador de carga mientras se descarga la ruta.
Ejemplo Avanzado: Modales con Lazy Loading
Componente Modal
Crea un modal como componente diferido.
1// Modal.js 2import React from "react"; 3 4function Modal({ onClose }) { 5 return ( 6 <div style={modalStyles}> 7 <div style={contentStyles}> 8 <h2>Este es un modal</h2> 9 <button onClick={onClose}>Cerrar</button> 10 </div> 11 </div> 12 ); 13} 14 15const modalStyles = { 16 position: "fixed", 17 top: 0, 18 left: 0, 19 width: "100%", 20 height: "100%", 21 backgroundColor: "rgba(0, 0, 0, 0.5)", 22 display: "flex", 23 justifyContent: "center", 24 alignItems: "center", 25}; 26 27const contentStyles = { 28 backgroundColor: "white", 29 padding: "20px", 30 borderRadius: "10px", 31}; 32 33export default Modal;
Usar el Modal con Lazy Loading
1import React, { useState, Suspense } from "react"; 2 3const Modal = React.lazy(() => import("./Modal")); 4 5function App() { 6 const [mostrarModal, setMostrarModal] = useState(false); 7 8 return ( 9 <div> 10 <h1>Ejemplo de Modal con Lazy Loading</h1> 11 <button onClick={() => setMostrarModal(true)}>Abrir Modal</button> 12 <Suspense fallback={<p>Cargando modal...</p>}> 13 {mostrarModal && <Modal onClose={() => setMostrarModal(false)} />} 14 </Suspense> 15 </div> 16 ); 17} 18 19export default App;
Ventaja
El modal solo se descarga y renderiza cuando el usuario hace clic en "Abrir Modal", reduciendo el tamaño del paquete inicial.
Consideraciones Importantes
-
Suspensees obligatorio
Siempre usaReact.Suspensepara envolver componentes cargados conReact.lazy. -
Cargar recursos dinámicos
AunqueReact.lazycarga componentes dinámicamente, no incluye estilos ni recursos externos, por lo que debes gestionarlos manualmente. -
Error Boundaries
Usa un Error Boundary para manejar posibles errores durante la carga del componente.
Añadiendo un Error Boundary
React no maneja errores en componentes diferidos automáticamente. Crea un Error Boundary para capturar problemas.
Error Boundary
1import React from "react"; 2 3class ErrorBoundary extends React.Component { 4 constructor(props) { 5 super(props); 6 this.state = { hasError: false }; 7 } 8 9 static getDerivedStateFromError() { 10 return { hasError: true }; 11 } 12 13 componentDidCatch(error, errorInfo) { 14 console.error("Error capturado:", error, errorInfo); 15 } 16 17 render() { 18 if (this.state.hasError) { 19 return <h1>Algo salió mal.</h1>; 20 } 21 22 return this.props.children; 23 } 24} 25 26export default ErrorBoundary;
Usar Error Boundary
1import React, { Suspense } from "react"; 2import ErrorBoundary from "./ErrorBoundary"; 3const ComponenteDiferido = React.lazy(() => import("./ComponenteDiferido")); 4 5function App() { 6 return ( 7 <ErrorBoundary> 8 <Suspense fallback={<p>Cargando...</p>}> 9 <ComponenteDiferido /> 10 </Suspense> 11 </ErrorBoundary> 12 ); 13} 14 15export default App;
Conclusión
React.lazy es una herramienta poderosa para optimizar la carga de componentes en React. Es ideal para:
- Dividir código en aplicaciones grandes.
- Rutas de navegación diferidas.
- Componentes condicionales como modales y tooltips.