TechLead

Características de React 19

Hook use(), Actions, useFormStatus, useOptimistic y el Compilador de React

Novedades en React 19

React 19 es una versión mayor que introduce nuevos primitivos para manejar operaciones asíncronas, formularios y actualizaciones optimistas. Estas características simplifican patrones que antes requerían código repetitivo complejo o librerías externas.

🚀 Características Clave de React 19

  • use() — Leer promesas y contexto en el renderizado
  • Actions — Transiciones asíncronas con estados pendientes automáticos
  • useFormStatus() — Rastrear el estado de envío de formularios
  • useOptimistic() — Actualizaciones optimistas de UI
  • useActionState() — Gestionar estado y errores de acciones
  • Compilador React — Memoización automática
  • ref como prop — Ya no se necesita forwardRef

El Hook use()

use() permite leer el valor de una Promesa o Contexto directamente durante el renderizado. A diferencia de otros hooks, use() puede llamarse dentro de condicionales y bucles.

import { use, Suspense } from 'react';

function UserProfile({ userPromise }) {
  const user = use(userPromise); // Suspende hasta que la promesa se resuelve

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

function App() {
  const userPromise = fetchUser(1);
  return (
    <Suspense fallback={<p>Cargando usuario...</p>}>
      <UserProfile userPromise={userPromise} />
    </Suspense>
  );
}

useActionState

useActionState gestiona el ciclo completo de una acción de formulario — estado, estado pendiente y manejo de errores en un solo hook:

import { useActionState } from 'react';

async function addTodo(previousState, formData) {
  const title = formData.get('title');
  if (!title) {
    return { error: 'El titulo es requerido', todos: previousState.todos };
  }
  const newTodo = await saveTodo({ title });
  return { error: null, todos: [...previousState.todos, newTodo] };
}

function TodoForm() {
  const [state, formAction, isPending] = useActionState(addTodo, {
    error: null, todos: [],
  });

  return (
    <form action={formAction}>
      <input name="title" placeholder="Nueva tarea..." />
      <button disabled={isPending}>
        {isPending ? 'Agregando...' : 'Agregar Tarea'}
      </button>
      {state.error && <p className="text-red-500">{state.error}</p>}
    </form>
  );
}

useOptimistic

useOptimistic muestra un estado optimista (predicho) mientras una acción asíncrona está en progreso:

import { useOptimistic, useTransition } from 'react';

function MessageList({ messages, sendMessage }) {
  const [optimisticMessages, addOptimistic] = useOptimistic(
    messages,
    (currentMessages, newMessage) => [
      ...currentMessages,
      { ...newMessage, sending: true },
    ]
  );

  const [, startTransition] = useTransition();

  async function handleSend(formData) {
    const text = formData.get('message');
    startTransition(async () => {
      addOptimistic({ id: Date.now(), text, sending: true });
      await sendMessage(text);
    });
  }

  return (
    <div>
      {optimisticMessages.map(msg => (
        <div key={msg.id} className={msg.sending ? 'opacity-60' : ''}>
          {msg.text}
          {msg.sending && <span className="text-xs"> (enviando...)</span>}
        </div>
      ))}
      <form action={handleSend}>
        <input name="message" />
        <button>Enviar</button>
      </form>
    </div>
  );
}

ref como Prop (Sin forwardRef)

// React 18 — necesitaba forwardRef
const Input = forwardRef(function Input(props, ref) {
  return <input ref={ref} {...props} />;
});

// React 19 — ref es solo un prop!
function Input({ ref, ...props }) {
  return <input ref={ref} {...props} />;
}

✅ Consejos de Migración

  • • React 19 es retrocompatible — el código existente sigue funcionando
  • • Comienza reemplazando forwardRef con ref-como-prop
  • • Adopta useActionState para formularios en código nuevo
  • • Usa useOptimistic para reemplazar patrones manuales de actualizaciones optimistas
  • • El Compilador de React es opt-in — actívalo por archivo o carpeta