Inicio / Artículos / Guía de entrevista para React: hooks, renderizado y lo que preguntan las grandes empresas

Guía de entrevista para React: hooks, renderizado y lo que preguntan las grandes empresas

DOM virtual, trampas de los hooks, rendimiento, gestión de estado, React 18, ejercicios de codificación en vivo y cómo explicar las razones detrás de las actualizaciones de la interfaz.

1332 palabras

En las entrevistas de React para empresas grandes rara vez se evalúa al candidato por su capacidad para recitar documentación. Lo que realmente importa es si sabe qué ocurre en el fondo: por qué un componente se vuelve a renderizar, por qué un efecto se ejecuta dos veces, por qué una actualización de estado no se muestra de inmediato. Los candidatos que pueden explicar por qué superan a aquellos que solo saben cómo.

A continuación se detallan los temas habituales que suelen surgir: fundamentos, hooks, rendimiento, patrones y las preguntas inesperadas que aparecen en todas partes.

1. Fundamentos básicos

Las preguntas de calentamiento casi siempre abarcan:

  • Virtual DOM — qué es y por qué las actualizaciones parecen más rápidas (proceso de diferenciación/reconciliación en lugar de escrituras directas en el DOM).
  • Reconciliación — cómo React decide qué actualizar (uso de claves, verificación del tipo de elemento).
  • JSX — una sintaxis simplificada que se compila a React.createElement(); hay que conocerlo bien.
  • Controlados vs. no controlados — los inputs controlados siguen el estado de React (value + onChange); los no controlados leen el DOM a través de refs.
  • Props vs. estado — los props son de solo lectura y provienen desde arriba; el estado es local y se modifica mediante setters o hooks.
  • Claves de lista — usar el índice como clave falla cuando cambia el orden (se reutiliza incorrectamente el DOM o el estado).
  • Pregunta engañosa: “¿Por qué no usar el índice del array como clave?” Responda con un ejemplo concreto de reordenamiento o inserción donde React asocie el estado a la fila incorrecta.

    2. Hooks (la sección más extensa de las entrevistas)

    useState

    • Las actualizaciones son asíncronas y se agrupan.
    • Cierres obsoletos: varias llamadas a setCount(count + 1) en un mismo evento comparten el mismo count; setCount(prev => prev + 1) lo soluciona.

    useEffect

    • Dependencias: [] una vez, se omiten en cada renderizado; solo se listan las dependencias cuando cambian.
    • Tiempo y propósito de la limpieza (fugas, cancelación de suscripciones/busquedas).
    • Por qué los efectos se ejecutan dos veces en desarrollo — El Modo Estricto de React 18 llama dos veces para detectar la falta de limpieza. Casi todos se encuentran con esto al menos una vez.

    useMemo vs useCallback

    • useMemo almacena un valor; useCallback almacena la identidad de una función.
    • Ambos protegen la igualdad referencial para los hijos de React.memo o las arrays de dependencias.
    • El uso excesivo tiene un costo; a los entrevistadores les gusta saber que la memorización no es gratuita.

    useRef

    • Valor mutable entre renderizados sin volver a renderizar.
    • Nodos DOM, valores anteriores, IDs de temporizadores.

    useContext

    • Termina el perforado de propiedades para un subárbol.
    • Atención: una actualización de contexto vuelve a renderizar todos los consumidores del subárbol, incluidos aquellos que solo leen un campo.

    useReducer

    • Preferirlo cuando la lógica es compleja o varios campos se actualizan juntos (reductores similares a Redux locales).

    Gancho personalizados

    • Estar preparado para escribir useDebounce, useFetch o useLocalStorage en tiempo real: uno de los ejercicios prácticos más comunes.

    3. Renderizado y rendimiento

    En las rondas intermedias y avanzadas es aquí donde se separan los participantes.

    • ¿Por qué volver a renderizar? Cuando se vuelve a renderizar el padre, cambia el estado, cambia el contexto, o las propiedades parecen iguales pero son referencias nuevas.
    • React.memo — compara propiedades de forma superficial; es inútil si se pasan objetos/funciones nuevos cada vez (usarlo junto con useMemo/useCallback).
  • División de código — React.lazy + Suspense.
  • Virtualización por ventanas — virtualización al estilo de react-window para listas muy largas.
  • Menos actualizaciones — desplaza el estado hacia abajo, divide los contextos y memoriza intencionadamente.
  • Analizador de rendimiento — mide en lugar de adivinar.
  • Pregunta clásica: una lista de 10,000 filas se vuelve lenta al escribir en el buscador. Se deben utilizar funciones de retardo, virtualización y filas memorizadas.

    4. Gestión de estado

    • Estado local vs global vs del servidor — nombrar el estado del servidor (caché, revalidación, carga/error) por separado del estado de la interfaz impresiona a los equipos técnicos.
    • Context vs Redux/Zustand — Context para globales poco comunes (tema, autenticación); Redux/Zustand cuando se necesitan middleware, herramientas, actualizaciones complejas o escrituras frecuentes sin problemas de sobrecarga del contexto.
    • React Query / SWR / TanStack Query — caché, recarga en segundo plano, eliminación de duplicados para evitar reinventar la capa de fetch de useEffect.
    • Conceptos básicos de Redux (si la pila lo utiliza): acciones, reducidores, almacén de estado, middleware thunk/saga, reducidores puros.

    5. Patrones de diseño

    • HOCs — envolver un componente; el clásico ejemplo es withAuth.
    • Render props — compartir lógica a través de una propiedad funcional; en su mayoría reemplazados por hooks, pero aún se pregunta sobre el concepto.
    • Componentes compuestos — componentes hermanos que comparten estado implícito mediante contexto (Select / Select.Option).
    • Componentes contenedor/presentacionales — separación entre datos y interfaz de usuario; menos rígida con hooks, pero la separación de responsabilidades sigue siendo importante.
    • Composición sobre herencia — el enfoque preferido de React para la reutilización; prepárese para justificarlo.

    6. Ciclo de vida de las clases (todavía se pregunta)

    Aquellos que priorizan los hooks aún investigan las bases fundamentales o los conjuntos de código heredados.

    • componentDidMount ≈ useEffect(() => {}, [])
    • componentDidUpdate ≈ efecto con dependencias
    • componentWillUnmount ≈ limpieza de efectos
    • Límites de errores — solo en clases (componentDidCatch / getDerivedStateFromError); los hooks no cuentan con algo similar, por lo que existen envoltorios como react-error-boundary.

    7. Conocimiento de React 18+

    • Renderizado concurrente — tareas interrumpibles para una interfaz de usuario más ágil.
    • useTransition — marcar actualizaciones no urgentes para mantener una respuesta rápida al escribir.
    • useDeferredValue — retrasa la interfaz de usuario que no es crítica.
    • Batching automático — agrupa operaciones dentro de promesas, tiempos de espera y controladores nativos (no solo los de React).
    • Suspense para datos — es más relevante en arquitecturas al estilo Next.js/Remix.
    • Componentes del servidor — qué se ejecuta dónde y por qué los paquetes del cliente se reducen de tamaño.

    8. JavaScript que se cuela sin ser notado

    • Cierres — estado obsoleto de los hooks.
    • Bucle de eventos / tareas micro frente a macro — por qué el batching funciona de la manera en que lo hace.
    • Vinculación de this — si aparecen clases.
    • Debounce vs throttle — casi siempre se recomienda, a menudo como solución para “optimizar este cuadro de búsqueda”.
    • Comparación superficial vs profunda — React.memo / useMemo y por qué los literales de objeto impiden la memorización.
    • Promesas / async-await — competencias entre solicitudes cuando los usuarios escriben rápidamente.

    9. Pruebas

    • Testing Library — enfoque en el comportamiento而非 en los detalles internos (búsquedas por rol o texto).
    • Jest — simulación de APIs; conocer los límites de las capturas de estado.
    • Pruebas unitarias vs. de integración vs. end-to-end, y dónde suelen situarse las pruebas de componentes.

    10. Codificación en vivo que se repite

    • Búsqueda/autocompletado con retardo
    • useFetch personalizado con estados de carga/error/datos
    • Desplazamiento infinito o paginación
    • Modales mediante portal (createPortal) y por qué existen los portales (evitar desbordamiento/z-index mientras se mantiene en el árbol de React para eventos/contexto)
    • Contador con funciones de deshacer/hacer mediante useReducer
    • Detección de errores por cierres obsoletos o dependencias faltantes

    Ejemplo paso a paso

    “¿Por qué este useEffect entra en bucle infinito?”

    useEffect(() => {
      setData({ ...data, updated: true });
    }, [data]);
    

    Respuesta sólida: el efecto enumera data como dependencia y luego escribe un objeto nuevo en data, de modo que cada ejecución cambia la dependencia y vuelve a activarlo inmediatamente. La solución consiste en eliminar data de las dependencias cuando no debería reactivarse, mover la actualización fuera del efecto o utilizar un actualizador funcional con dependencias más estrictas.

    Explicar por qué falla, y no solo proponer una corrección, es lo que distingue a las buenas respuestas en entrevistas de React.

    Cierre

    La profundidad de conocimiento supera a la memorización superficial de las API. Los entrevistadores buscan información sobre el comportamiento de renderizado, los cierres de funciones y los compromisos en cuanto al rendimiento: esos son los errores que aparecen en producción. Prepárate creando componentes pequeños que fallen intencionadamente (cierres de funciones obsoletos, dependencias faltantes, renders innecesarios) y arreglándolos. Ese instinto para depurar es lo que realmente se evalúa en la entrevista.

    Cuando practiques, ponle un límite de tiempo al igual que en las entrevistas: explica el Virtual DOM en sesenta segundos, luego depura un fragmento con cierres de funciones obsoletos y después esboza una función de búsqueda con debounce. Ese orden coincide con el modo en que realmente se desarrollan las tareas durante la entrevista.

    Cómo suelen evolucionar los paneles

    Los calentamientos se centran en el Virtual DOM, los controles de entrada y las teclas. En las rondas intermedias se pasan a los hooks: actualizaciones por lotes, efectos dobles en Modo Estricto, memo versus callback, y cómo escribir un hook personalizado en tiempo real. En las rondas avanzadas se abordan temas de rendimiento: listas de diez mil filas, problemas con el contexto, evidencia del Profiler, y decisiones arquitectónicas entre Context, Redux/Zustand y TanStack Query para el estado del servidor.

    Mantén un repositorio personal de “errores intencionados”: un contador de cierres obsoletos, un efecto por dependencias faltantes, una lista memorizada que sigue renderizándose debido a objetos incrustados, y un modal tipo portal. Explicar oralmente esas cuatro soluciones cubre una proporción sorprendente del tiempo dedicado al coding en vivo y a las explicaciones en pizarra.

    Si el puesto menciona React 18+, prepárate con una oración cada una sobre renderizado concurrente, transiciones, valores diferidos, agrupamiento automático y Componentes del Servidor. Un conocimiento profundo de un caso práctico concreto es mejor que una conciencia vaga de todos los RFC.

    Lecturas relacionadas

  • Errores técnicos de SEO en frontend de JavaScript moderno — Renderizado solo en el cliente, metadatos inestables, semántica, CWV, errores con robots y rutas dinámicas — soluciones para equipos de ingeniería.
  • La velocidad de React comienza con la organización del árbol de componentes — Las re-renderizaciones no son el enemigo; lo es la propagación excesiva del estado. Mueva las fuentes hacia las hojas antes de aplicar micromemorización.