Autenticación y Prop Drilling
Introducción
En esta clase continuamos con el proyecto de React Router. Ya teníamos rutas, lazy load implementado y diferentes páginas funcionando correctamente. Ahora queremos añadir un concepto fundamental en cualquier aplicación: autenticación.
Todavía no vamos a implementar autenticación real. Vamos a simular que el usuario inicia sesión y ver cómo gestionar ese estado en React. Esta clase es clave porque nos llevará directamente al problema del prop drilling, que más adelante resolveremos con Zustand u otros patrones.
Objetivo de la clase
Vamos a:
- Crear un estado de autenticación en el componente raíz
App - Pasar ese estado a componentes que lo necesitan (header y página de detalle)
- Simular login y logout
- Restringir la acción de “Aplicar a un trabajo” a usuarios autenticados
- Descubrir los problemas de rendimiento y escalabilidad del prop drilling
Situación inicial del proyecto
El proyecto tiene:
- React Router configurado
- Lazy load funcionando (solo se cargan los bundles necesarios por ruta)
- Varias páginas: Home, Search, Job Detail, NotFound
- Un
Headerdonde colocaremos el botón de iniciar/cerrar sesión
La clase retoma desde este punto.
Añadiendo el estado de autenticación
El estado de autenticación debe estar en un lugar accesible a toda la app.
Por eso se coloca en App.jsx:
const [isLoggedIn, setIsLoggedIn] = useState(false)
const login = () => setIsLoggedIn(true)
const logout = () => setIsLoggedIn(false)
Ahora queremos que:
- El Header pueda mostrar “Iniciar sesión” o “Cerrar sesión”
- El JobDetailPage sepa si el usuario está logueado para permitir o no aplicar a un trabajo
Así que pasamos estas props:
<Header
isLoggedIn={isLoggedIn}
onLogin={login}
onLogout={logout}
/>
<JobDetailPage
isLoggedIn={isLoggedIn}
/>
Esto funciona perfectamente… pero en cuanto la app crece, empiezan los problemas.
Añadiendo el login en el Header
En Header.jsx:
function Header({ isLoggedIn, onLogin, onLogout }) {
return (
<header>
{isLoggedIn ? (
<button onClick={onLogout}>Cerrar sesión</button>
) : (
<button onClick={onLogin}>Iniciar sesión</button>
)}
</header>
)
}
Ahora el usuario puede iniciar y cerrar sesión, y el botón cambia automáticamente.
Usando la autenticación en la página de detalle
En JobDetailPage.jsx:
function JobDetailPage({ isLoggedIn }) {
return (
<button disabled={!isLoggedIn}>
{isLoggedIn ? 'Aplicar ahora' : 'Inicia sesión para aplicar'}
</button>
)
}
Esto funciona, pero ahora empieza el verdadero problema.
El problema: Prop Drilling
Hasta ahora todo es sencillo: el estado baja un nivel desde App hasta JobDetailPage.
Pero en el vídeo empezamos a dividir JobDetailPage en más componentes:
- JobDetailHeader
- JobDetailBreadcrumb
- JobDetailApplyButton
- Etc.
Y cada uno de esos niveles necesita recibir isLoggedIn como prop.
Esto provoca que:
App
└─ JobDetailPage (recibe isLoggedIn)
└─ JobDetailHeader (recibe isLoggedIn)
└─ JobDetailApplyButton (recibe isLoggedIn)
A más componentes, más niveles. Y a más niveles, más prop drilling.
Prop drilling consiste en “taladrar” la prop hacia abajo sin que algunos componentes intermedios la necesiten realmente.
Problemas que causa el prop drilling
1. Código difícil de mantener
Para usar una prop en un componente profundo, debes pasarla por todos los de en medio.
2. Acoplamiento innecesario
Componentes que no necesitan isLoggedIn se ven obligados a recibirlo y reenviarlo.
3. Rendimiento pobre
Usando React DevTools (highlight updates), se ve que:
- Al iniciar o cerrar sesión, gran parte de la app se vuelve a renderizar
- Incluso componentes que no dependen del estado se actualizan igualmente
Esto sucede porque el estado vive demasiado arriba.
Demostración vista en el vídeo: casi toda la pantalla se ilumina de “updates”.
Intento de solución parcial: Composición
En el vídeo se intenta usar composición para reducir niveles:
<JobDetailPage>
<JobDetailHeader isLoggedIn={isLoggedIn} />
</JobDetailPage>
Esto ayuda un poco, pero:
- El estado sigue estando en App
- Sigue siendo necesario pasarlo por props
- La propagación hacia abajo continúa
Conclusión: la composición no es suficiente.
Conclusión de la clase
En esta lección hemos visto:
- ✓ Cómo simular autenticación con estado en React
- ✓ Cómo pasar login/logout a componentes como el header
- ✓ Cómo restringir acciones basadas en si el usuario está autenticado
- ✓ Cómo dividir componentes en subcomponentes más pequeños
- ✓ Cómo se produce el prop drilling al escalar la UI
- ✓ Cómo React DevTools permite visualizar renderizados innecesarios
- ✓ Por qué este patrón no escala y afecta al rendimiento
Esta clase prepara el terreno para introducir una solución mucho mejor:
Estado global con Zustand, evitando prop drilling y re-renderizados innecesarios.
Esto lo veremos en la próxima clase.