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

  1. React.lazy: Carga el componente solo cuando es necesario (ComponentePesado).
  2. Suspense: Muestra un contenido de carga (<p>Cargando...</p>) mientras el componente se descarga.
  3. 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

  1. React.lazy: Cada ruta (Home y About) se carga solo cuando se visita.
  2. 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

  1. Suspense es obligatorio
    Siempre usa React.Suspense para envolver componentes cargados con React.lazy.

  2. Cargar recursos dinámicos
    Aunque React.lazy carga componentes dinámicamente, no incluye estilos ni recursos externos, por lo que debes gestionarlos manualmente.

  3. 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.