🚀 ¡Las clases del Bootcamp vuelven el 7 de enero con Node.js! Cargando...

Usar use en lugar de useContext

En las clases anteriores hemos trabajado con useContext para consumir contextos en React. Es la forma tradicional que llevamos usando años. Pero desde React 19 existe una nueva utilidad llamada use que simplifica aún más la sintaxis y añade capacidades adicionales.

En esta clase verás cómo funciona use, por qué es útil y cuándo usarlo en lugar de useContext.


¿Qué es use?

use es una nueva utilidad de React que permite leer:

  1. Contextos (como useContext, pero más simple)
  2. Promesas (para trabajar con datos asíncronos)

Características principales

use vs useContext
──────────────────

✅ Sintaxis más corta
✅ Menos imports necesarios
✅ Puede leer promesas (no solo contextos)
✅ Más declarativo
✅ Parte de React 19+

La ventaja principal es la simplicidad: menos código, misma funcionalidad.


Comparando useContext y use

Veamos la diferencia en código real.

Forma clásica con useContext

import { useContext } from 'react'
import { AuthContext } from './context/authContext'

export function Header() {
  const { isLogin, login, logout } = useContext(AuthContext)

  return (
    <header>
      {isLogin ? (
        <button onClick={logout}>Cerrar sesión</button>
      ) : (
        <button onClick={login}>Iniciar sesión</button>
      )}
    </header>
  )
}

Forma moderna con use

import { use } from 'react'
import { AuthContext } from './context/authContext'

export function Header() {
  const { isLogin, login, logout } = use(AuthContext)

  return (
    <header>
      {isLogin ? (
        <button onClick={logout}>Cerrar sesión</button>
      ) : (
        <button onClick={login}>Iniciar sesión</button>
      )}
    </header>
  )
}

Diferencias visuales

ANTES (useContext)              DESPUÉS (use)
──────────────────              ─────────────

import { useContext }           import { use }
useContext(AuthContext)         use(AuthContext)

Más verboso                     Más conciso
Solo contextos                  Contextos + Promesas

Resultado: Exactamente el mismo. Solo cambia la sintaxis.


Actualizando nuestro custom hook

En la clase anterior creamos un custom hook useAuth(). Podemos actualizarlo para usar use en lugar de useContext:

Antes (con useContext)

import { createContext, useContext, useState } from 'react'

export const AuthContext = createContext()

export function useAuth() {
  const context = useContext(AuthContext)

  if (context === undefined) {
    throw new Error('useAuth debe usarse dentro de un AuthProvider')
  }

  return context
}

export function AuthProvider({ children }) {
  const [isLogin, setIsLogin] = useState(false)

  const login = () => setIsLogin(true)
  const logout = () => setIsLogin(false)

  const value = { isLogin, login, logout }

  return <AuthContext value={value}>{children}</AuthContext>
}

Después (con use)

import { createContext, use, useState } from 'react'

export const AuthContext = createContext()

export function useAuth() {
  const context = use(AuthContext)

  if (context === undefined) {
    throw new Error('useAuth debe usarse dentro de un AuthProvider')
  }

  return context
}

export function AuthProvider({ children }) {
  const [isLogin, setIsLogin] = useState(false)

  const login = () => setIsLogin(true)
  const logout = () => setIsLogin(false)

  const value = { isLogin, login, logout }

  return <AuthContext value={value}>{children}</AuthContext>
}

Cambios realizados

- import { createContext, useContext, useState } from 'react'
+ import { createContext, use, useState } from 'react'

  export function useAuth() {
-   const context = useContext(AuthContext)
+   const context = use(AuthContext)

    if (context === undefined) {
      throw new Error('useAuth debe usarse dentro de un AuthProvider')
    }

    return context
  }

Solo dos líneas cambian. El resto del código permanece idéntico.


Simplificación del Provider

React 19 también simplifica la sintaxis del Provider. Ya no necesitas escribir .Provider:

Sintaxis clásica

<AuthContext.Provider value={value}>
  <App />
</AuthContext.Provider>

Sintaxis moderna

<AuthContext value={value}>
  <App />
</AuthContext>

Ambas funcionan igual. La segunda es más limpia.

Ejemplo completo

export function AuthProvider({ children }) {
  const [isLogin, setIsLogin] = useState(false)

  const login = () => setIsLogin(true)
  const logout = () => setIsLogin(false)

  const value = { isLogin, login, logout }

  // ✅ Sintaxis moderna (React 19+)
  return <AuthContext value={value}>{children}</AuthContext>

  // ✅ Sintaxis clásica (sigue funcionando)
  // return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>
}

Capacidades adicionales de use

A diferencia de useContext, use también puede leer promesas. Esto es útil para cargar datos de forma asíncrona.

Ejemplo con promesas

import { use } from 'react'

async function fetchUser() {
  const response = await fetch('/api/user')
  return response.json()
}

export function UserProfile() {
  // ✨ use puede leer promesas directamente
  const user = use(fetchUser())

  return (
    <div>
      <h1>{user.name}</h1>
      <p>{user.email}</p>
    </div>
  )
}

Comparación con useEffect

Antes (con useEffect):

import { useState, useEffect } from 'react'

export function UserProfile() {
  const [user, setUser] = useState(null)
  const [loading, setLoading] = useState(true)

  useEffect(() => {
    fetch('/api/user')
      .then((res) => res.json())
      .then((data) => {
        setUser(data)
        setLoading(false)
      })
  }, [])

  if (loading) return <p>Cargando...</p>

  return (
    <div>
      <h1>{user.name}</h1>
      <p>{user.email}</p>
    </div>
  )
}

Después (con use):

import { use } from 'react'

export function UserProfile() {
  const user = use(fetchUser())

  return (
    <div>
      <h1>{user.name}</h1>
      <p>{user.email}</p>
    </div>
  )
}

Nota: Para que esto funcione correctamente, necesitas usar Suspense para manejar el estado de carga:

import { Suspense } from 'react'

function App() {
  return (
    <Suspense fallback={<p>Cargando...</p>}>
      <UserProfile />
    </Suspense>
  )
}

Compatibilidad y migración

¿Desde cuándo está disponible?

use está disponible desde React 19. Si usas una versión anterior, necesitas actualizar.

¿Debo migrar todo mi código?

No es necesario. useContext sigue funcionando perfectamente y no está deprecado.

ESTRATEGIA DE MIGRACIÓN
───────────────────────

✅ Proyectos nuevos → Usa use desde el inicio
✅ Código existente → Migra gradualmente (opcional)
✅ Librerías → Mantén useContext por compatibilidad
✅ Aprendizaje → Aprende ambas, usa la que prefieras

Tabla de compatibilidad

CaracterísticauseContextuse
Leer contextos✅ Sí✅ Sí
Leer promesas❌ No✅ Sí
Versión mínimaReact 16.3+React 19+
EstadoEstableEstable
Deprecado❌ No❌ No

Ventajas de usar use

1. Menos verbosidad

// Antes
import { useContext } from 'react'
const value = useContext(MyContext)

// Después
import { use } from 'react'
const value = use(MyContext)

2. API unificada

// Un solo hook para múltiples casos
const context = use(MyContext) // Leer contexto
const data = use(fetchData()) // Leer promesa

3. Código más declarativo

// Más claro y directo
function Component() {
  const theme = use(ThemeContext)
  const user = use(fetchUser())

  return <div style={{ color: theme.color }}>{user.name}</div>
}

Ejemplo completo: Antes y después

Aplicación completa con useContext

// authContext.jsx
import { createContext, useContext, useState } from 'react'

export const AuthContext = createContext()

export function useAuth() {
  const context = useContext(AuthContext)
  if (!context) throw new Error('useAuth fuera de AuthProvider')
  return context
}

export function AuthProvider({ children }) {
  const [isLogin, setIsLogin] = useState(false)
  const value = {
    isLogin,
    login: () => setIsLogin(true),
    logout: () => setIsLogin(false),
  }
  return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>
}

// Header.jsx
import { useAuth } from './authContext'

export function Header() {
  const { isLogin, login, logout } = useAuth()
  return (
    <header>
      {isLogin ? <button onClick={logout}>Salir</button> : <button onClick={login}>Entrar</button>}
    </header>
  )
}

Aplicación completa con use

// authContext.jsx
import { createContext, use, useState } from 'react'

export const AuthContext = createContext()

export function useAuth() {
  const context = use(AuthContext)
  if (!context) throw new Error('useAuth fuera de AuthProvider')
  return context
}

export function AuthProvider({ children }) {
  const [isLogin, setIsLogin] = useState(false)
  const value = {
    isLogin,
    login: () => setIsLogin(true),
    logout: () => setIsLogin(false),
  }
  return <AuthContext value={value}>{children}</AuthContext>
}

// Header.jsx
import { useAuth } from './authContext'

export function Header() {
  const { isLogin, login, logout } = useAuth()
  return (
    <header>
      {isLogin ? <button onClick={logout}>Salir</button> : <button onClick={login}>Entrar</button>}
    </header>
  )
}

Diferencias marcadas

  // authContext.jsx
- import { createContext, useContext, useState } from 'react'
+ import { createContext, use, useState } from 'react'

  export function useAuth() {
-   const context = useContext(AuthContext)
+   const context = use(AuthContext)
    if (!context) throw new Error('useAuth fuera de AuthProvider')
    return context
  }

  export function AuthProvider({ children }) {
    const [isLogin, setIsLogin] = useState(false)
    const value = { /* ... */ }
-   return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>
+   return <AuthContext value={value}>{children}</AuthContext>
  }

Solo 3 líneas cambian en todo el código.


¿Cuándo usar use vs useContext?

Usa use cuando:

  • ✅ Estás en React 19+
  • ✅ Quieres código más conciso
  • ✅ Necesitas leer promesas además de contextos
  • ✅ Estás empezando un proyecto nuevo

Usa useContext cuando:

  • ✅ Necesitas compatibilidad con React < 19
  • ✅ Trabajas en una librería pública
  • ✅ El equipo no está familiarizado con use
  • ✅ Prefieres la sintaxis tradicional

Ambas opciones son válidas. No hay una “correcta” o “incorrecta”.


Resumen de la clase

En esta clase has aprendido:

  1. Qué es use: Nueva utilidad de React 19 para leer contextos y promesas
  2. Cómo migrar de useContext a use: Cambiar el import y la llamada
  3. Simplificación del Provider: Ya no necesitas .Provider
  4. Capacidades adicionales: use puede leer promesas, no solo contextos
  5. Compatibilidad: useContext sigue funcionando, no está deprecado
  6. Cuándo usar cada uno: Depende de tu versión de React y preferencias

Conclusión

use es la evolución natural de useContext: misma funcionalidad, menos código.

useContext → use
──────────────────

Funcionalidad:  Idéntica
Sintaxis:       Más simple
Capacidades:    Más amplia (+ promesas)
Compatibilidad: React 19+

Recomendación: Si estás en React 19+, prueba use. Si no, useContext sigue siendo perfecto.

En la siguiente clase exploraremos Zustand, una librería de gestión de estado que soluciona las limitaciones de rendimiento de Context con una API aún más simple.