10.4-¿Qué es DESMONTAR un Componente en React
¿Qué es DESMONTAR un Componente en React?
En 1 SEGUNDO:
Desmontar = ELIMINAR el componente de la pantalla. Como cerrar una ventana en tu computadora.
📌 Analogía Simple:
MONTAR = Abrir una App en tu celular
jsx
// Presionas el ícono de WhatsApp
// WhatsApp se "monta" en pantalla
<WhatsApp /> → Aparece en tu pantalla ✅
DESMONTAR = Cerrar la App
jsx
// Presionas el botón Home
// WhatsApp se "desmonta" de la pantalla
<WhatsApp /> → Desaparece de tu pantalla ❌
📌 Ejemplo Visual en Código:
jsx
function App() {
const [mostrarLogin, setMostrarLogin] = useState(true);
return (
<div>
<button onClick={() => setMostrarLogin(false)}>
Cerrar Login
</button>
{/* Cuando mostrarLogin sea FALSE, Login se DESMONTA */}
{mostrarLogin && <LoginForm />}
</div>
);
}
Lo que pasa cuando haces click:
mostrarLogin cambia de true → false
React dice: "Ah, ya no necesito mostrar <LoginForm />"
DESMONTA el componente LoginForm
ELIMINA todo lo relacionado con LoginForm de la memoria
📌 ¿Qué se DESTRUYE al Desmontar?
Cuando un componente se desmonta, TODO se pierde:
jsx
function LoginForm() {
const [email, setEmail] = useState(''); // ❌ SE PIERDE
const [password, setPassword] = useState(''); // ❌ SE PIERDE
const [intentos, setIntentos] = useState(0); // ❌ SE PIERDE
useEffect(() => {
console.log('Montado!'); // Se ejecuta al MONTAR
return () => {
console.log('Desmontado!'); // Se ejecuta al DESMONTAR
};
}, []);
return <form>...</form>;}
Al desmontar LoginForm:
email = "usuario@ejemplo.com" → 💀 GONE
password = "123456" → 💀 GONE
intentos = 3 → 💀 GONE
Las funciones setEmail, setPassword → 💀 GONE
📌 Ciclo de Vida de un Componente:
text
NACE → VIVE → MUERE
↓ ↓ ↓
MONTAR ACTUALIZAR DESMONTAR
Ejemplo del Login:
text
1. Usuario abre la app: <LoginForm /> se MONTA ✅
- Aparece en pantalla
- useState() se ejecuta
- Se crean estados, efectos
2. Usuario escribe credenciales: <LoginForm /> se ACTUALIZA 🔄
- email cambia
- password cambia
- Componente se re-renderiza
3. Usuario hace login exitoso: <LoginForm /> se DESMONTA ❌
- Desaparece de pantalla
- Estados se destruyen
- Efectos se limpian
📌 Situaciones Comunes donde se Desmonta:
1. Navegación entre páginas:
jsx
// Página Actual → Nueva Página
<HomePage /> // Se DESMONTA ❌
↓
<ProfilePage /> // Se MONTA ✅
2. Mostrar/Ocultar elementos:
jsx
{mostrarPopup && <Popup />} // Al cambiar a false, Popup se DESMONTA
3. Renderizado condicional:
jsx
{estaCargando ? <Spinner /> : <Contenido />}
// Cuando deja de cargar, Spinner se DESMONTA
4. Listas dinámicas:
jsx
{tareas.map(tarea => (
<TareaItem key={tarea.id} /> // Si eliminas una tarea, se DESMONTA
))}
📌 ¿Por qué es importante saber esto?
Problema Común:
jsx
function Contador() {
const [contador, setContador] = useState(0);
useEffect(() => {
// ⚠️ PELIGRO: Si el componente se desmonta antes de 3 segundos...
setTimeout(() => {
setContador(contador + 1); // ❌ ERROR: Componente ya desmontado
}, 3000);
}, []);
return <div>{contador}</div>;
}
Solución:
jsx
useEffect(() => {
let estaMontado = true; // Bandera
setTimeout(() => {
if (estaMontado) { // ✅ Verificamos antes de actualizar
setContador(contador + 1);
}
}, 3000);
// Función de limpieza (se ejecuta al DESMONTAR)
return () => {
estaMontado = false; // Marcamos como desmontado
};
}, []);
📌 Regla de Oro:
"Todo lo que nace (se monta), eventualmente muere (se desmonta)"
En práctica:
Componentes temporales (popups, modales, loaders) → Se montan y desmontan frecuentemente
Componentes permanentes (App, Layout principal) → Se montan 1 vez al inicio
El estado LOCAL muere con el componente
El estado en el padre SOBREVIVE si el padre no se desmonta
🎯 Resumen en 3 puntos:
DESMONTAR = QUITAR de pantalla y eliminar de memoria
TODO el estado local se PIERDE al desmontar
Para datos importantes: guárdalos en el padre, localStorage, o base de datos
📱 Ejemplo Final del Mundo Real:
jsx
// Instagram Stories
function Stories() {
const [storyActual, setStoryActual] = useState(0);
return (
<div>
{/* Cada Story se MONTA cuando es su turno */}
{/* y se DESMONTA cuando termina/te sales */}
{stories.map((story, index) => (
index === storyActual && <Story key={story.id} story={story} />
))}
</div>
);
}
Cada Story:
Se MONTA cuando llega su turno ✅
Vive 15 segundos mostrándose ⏱️
Se DESMONTA cuando termina o saltas ❌
Su estado interno (pausado, mute, etc.) se PIERDE
¡Excelente pregunta! Te explico qué significa "desmontar" en React:
NO, useState([]) NO se desmonta. El que se desmonta es el COMPONENTE que contiene ese estado.
📌 ¿Qué significa "montar" y "desmontar"?
1. Montar (Mount)
jsx
// Cuando un componente APARECE por primera vez en pantalla
<App /> → React lo "monta" en el DOM
↓
useState([]) se EJECUTA por primera vez
↓
El componente se RENDERIZA en pantalla
2. Desmontar (Unmount)
jsx
// Cuando un componente DESAPARECE de pantalla
<App /> → React lo "elimina" del DOM
↓
El componente y TODO su estado se DESTRUYEN
↓
Ya no existe en memoria
📌 Ejemplo práctico:
jsx
function App() {
const [tasks, setTasks] = useState([]); // ✅ Se ejecuta al MONTAR
return (
<div>
{mostrarFormulario && <TaskForm />} {/* Puede montarse/desmontarse */}
</div>
);
}
function TaskForm() {
const [taskText, setTaskText] = useState(''); // ❗️Se DESTRUYE al desmontar
return <form>...</form>;
}
Flujo:
text
1. App se MONTA → useState([]) se ejecuta → tasks existe
2. Usuario hace algo que muestra TaskForm
3. TaskForm se MONTA → useState('') se ejecuta → taskText existe
4. Usuario hace algo que oculta TaskForm
5. TaskForm se DESMONTA → ⚠️ taskText se PIERDE para siempre
6. Si TaskForm vuelve a montarse: useState('') se ejecuta NUEVO → taskText = '' (vacío)
📌 ¿Qué exactamente se "destruye" al desmontar?
jsx
function TaskForm() {
// ESTO se CREA al montar:
const [taskText, setTaskText] = useState('');
const [contador, setContador] = useState(0);
const [lista, setLista] = useState([]);
// ESTO se DESTRUYE al desmontar:
// - El valor actual de taskText (ej: "Comprar leche")
// - El valor actual de contador (ej: 5)
// - El valor actual de lista (ej: [1, 2, 3])
// - Las funciones setTaskText, setContador, setLista
// - TODO el componente y su memoria
return <form>...</form>;
}
📌 Demo interactivo mental:
// Página 1: Lista de tareas
function PaginaTareas() {
const [tasks, setTasks] = useState([]); // ⚡️ Montado
// Usuario agrega tareas...
// tasks = ["Comprar leche", "Estudiar React"]
return <div>...</div>;
}
// Usuario navega a Página 2:
// 1. PaginaTareas se DESMONTA ⚡️
// 2. tasks = ["Comprar leche", "Estudiar React"] → SE PIERDE 💀
// 3. useState([]) → DEJA DE EXISTIR
// Usuario vuelve a Página 1:
// 1. PaginaTareas se MONTA NUEVAMENTE ⚡️
// 2. useState([]) se EJECUTA DE NUEVO
// 3. tasks = [] ← ¡VACÍO! Se reinició
📌 ¿Cómo evitamos perder datos al desmontar?
Opción 1: Subir el estado (lo que hace nuestro App.js)
jsx
// El estado vive en App (que NUNCA se desmonta)
function App() {
const [tasks, setTasks] = useState([]); // ✅ Persiste
return (
<div>
{/* TaskForm puede montarse/desmontarse sin perder tasks */}
<TaskForm onAddTask={addTask} />
<TaskList tasks={tasks} />
</div>
);
}
Opción 2: Guardar en localStorage
jsx
function App() {
const [tasks, setTasks] = useState(() => {
// Recuperar de localStorage al montar
const guardado = localStorage.getItem('tasks');
return guardado ? JSON.parse(guardado) : [];
});
// Guardar en localStorage cada cambio
useEffect(() => {
localStorage.setItem('tasks', JSON.stringify(tasks));
}, [tasks]);
}
Opción 3: Context API o Redux (estado global)
jsx
// El estado vive fuera de los componentes
const TasksContext = createContext();
function App() {
return (
<TasksContext.Provider value={{tasks, setTasks}}>
{/* Componentes pueden montarse/desmontarse */}
{/* pero acceden al estado global que persiste */}
</TasksContext.Provider>
);
}
📌 Resumen clave:
📌 Regla importante de React:
⚠️ Nunca llames setState en un componente desmontado
jsx
// ❌ PELIGROSO: Esto causa error
useEffect(() => {
setTimeout(() => {
setTasks([...]); // ⚠️ Si el componente se desmontó antes de 2 segundos, ERROR
}, 2000);
}, []);
// ✅ CORRECTO: Verificar si está montado
useEffect(() => {
let estaMontado = true;
setTimeout(() => {
if (estaMontado) {
setTasks([...]); // Solo si sigue montado
}
}, 2000);
return () => { estaMontado = false; }; // Cleanup al desmontar
}, []);
📌 En nuestro App.js original:
jsx
function App() {
const [tasks, setTasks] = useState([]); // ✅ Persiste
// App es el componente raíz, NUNCA se desmonta
// (a menos que cerremos la pestaña del navegador)
return ( ... );
}
Por eso tasks es seguro en App.js - porque App es el componente principal que siempre está montado mientras la aplicación esté abierta.
Comentarios
Publicar un comentario