Guía Completa de React 18 con TypeScript: Concurrent Features y Nuevos Hooks Complete Guide to React 18 with TypeScript: Concurrent Features and New Hooks

React 18 introdujo un cambio de paradigma: el Concurrent Renderer. Esto significa que React puede interrumpir, pausar y reanudar renders para mantener la UI responsiva. En esta guía aprenderás a aprovechar todas estas características usando TypeScript desde cero. React 18 introduced a paradigm shift: the Concurrent Renderer. This means React can interrupt, pause, and resume renders to keep the UI responsive. In this guide you'll learn to leverage all these features using TypeScript from scratch.

1. Configurar el proyecto con Vite + React 18 + TypeScript1. Set Up the Project with Vite + React 18 + TypeScript

Vite es actualmente la herramienta más rápida para crear proyectos React. El ecosistema ha migrado casi por completo de Create React App hacia Vite por su velocidad de HMR y tiempo de arranque casi instantáneo. Vite is currently the fastest tool for building React projects. The ecosystem has nearly fully migrated from Create React App to Vite for its HMR speed and near-instant startup time.

npm create vite@latest mi-app -- --template react-ts
cd mi-app
npm install
npm run dev

Esto genera un proyecto con React 18, TypeScript y el plugin oficial @vitejs/plugin-react que usa Babel por defecto. Si prefieres el compilador SWC (mucho más rápido en proyectos grandes), usa --template react-swc-ts. Babel by default. If you prefer the SWC compiler (much faster in large projects), use --template react-swc-ts.

2. Tipado estricto desde el principio2. Strict Typing from the Start

El tsconfig.json generado por Vite incluye "strict": true, que activa reglas que previenen errores comunes en tiempo de compilación. Las más importantes: The tsconfig.json generated by Vite includes "strict": true, activating rules that prevent common compile-time errors. The most important:

  • strictNullChecks: obliga a manejar null y undefined explícitamente.strictNullChecks: forces explicit handling of null and undefined.
  • noImplicitAny: prohíbe el tipo any implícito.noImplicitAny: forbids implicit any types.
  • strictFunctionTypes: valida correctamente los tipos de funciones en callbacks.strictFunctionTypes: correctly validates function types in callbacks.

Para componentes React con TypeScript, el patrón estándar es definir una interfaz para las props: For React components with TypeScript, the standard pattern is to define an interface for the props:

interface ButtonProps {
  label: string;
  onClick: () => void;
  variant?: 'primary' | 'ghost';
}

export function Button({ label, onClick, variant = 'primary' }: ButtonProps) {
  return (
    <button className={`btn btn--${variant}`} onClick={onClick}>
      {label}
    </button>
  );
}

3. El hook useTransition — renders no urgentes3. The useTransition Hook — Non-Urgent Renders

useTransition es el hook más importante de React 18. Permite marcar actualizaciones de estado como no urgentes, para que React las interrumpa si llega una actualización más prioritaria. useTransition is React 18's most important hook. It lets you mark state updates as non-urgent, so React can interrupt them when a higher-priority update arrives.

import { useState, useTransition } from 'react';

function SearchList() {
  const [query, setQuery] = useState('');
  const [results, setResults] = useState<string[]>([]);
  const [isPending, startTransition] = useTransition();

  function handleChange(e: React.ChangeEvent<HTMLInputElement>) {
    setQuery(e.target.value); // urgente: actualiza el input de inmediato

    startTransition(() => {
      // no urgente: filtra 10 000 items sin bloquear la UI
      setResults(heavyFilter(e.target.value));
    });
  }

  return (
    <>
      <input value={query} onChange={handleChange} placeholder="Buscar..." />
      {isPending ? <span>Cargando...</span> : <ul>{results.map(r => <li key={r}>{r}</li>)}</ul>}
    </>
  );
}

4. useDeferredValue — valor diferido para renders pesados4. useDeferredValue — Deferred Value for Heavy Renders

useDeferredValue es similar a useTransition pero actúa sobre un valor. Ideal cuando no controlas el estado que dispara el render costoso. useDeferredValue is similar to useTransition but acts on a value. Ideal when you don't directly control the state triggering the expensive render.

import { useDeferredValue, useMemo } from 'react';

function FilteredTable({ data, filter }: { data: Row[]; filter: string }) {
  const deferredFilter = useDeferredValue(filter);

  const filteredRows = useMemo(
    () => data.filter(row => row.name.includes(deferredFilter)),
    [data, deferredFilter]
  );

  return <Table rows={filteredRows} />;
}

5. Suspense con datos asincrónicos5. Suspense with Asynchronous Data

React 18 hace que Suspense sea compatible con la carga de datos. Junto con TanStack Query o el nuevo use() hook, puedes declarar la carga asincrónica de forma elegante: React 18 makes Suspense compatible with data loading (not just lazy imports). Together with TanStack Query or the new use() hook, you can handle async loading elegantly:

import { Suspense } from 'react';

async function UserProfile({ userId }: { userId: string }) {
  const user = await fetchUser(userId); // en React Server Components
  return <div>{user.name}</div>;
}

export function Page() {
  return (
    <Suspense fallback={<Skeleton />}>
      <UserProfile userId="123" />
    </Suspense>
  );
}

6. Mejores prácticas con TypeScript + React 186. Best Practices with TypeScript + React 18

  • Usa React.FC con moderación — preferir funciones normales con tipos explícitos.Use React.FC sparingly — prefer plain functions with explicit types.
  • Tipea los eventos del DOM: React.MouseEvent<HTMLButtonElement>, React.ChangeEvent<HTMLInputElement>.Type DOM events: React.MouseEvent<HTMLButtonElement>, React.ChangeEvent<HTMLInputElement>.
  • Prefiere as const sobre enum para uniones de strings.Prefer as const over enum for string unions.
  • Usa Readonly<T> y ReadonlyArray<T> para prevenir mutaciones accidentales.Use Readonly<T> and ReadonlyArray<T> to prevent accidental mutations.
  • Habilita exactOptionalPropertyTypes en tsconfig para tipado aún más estricto.Enable exactOptionalPropertyTypes in tsconfig for even stricter typing.

ConclusiónConclusion

React 18 con TypeScript es la combinación ideal para construir aplicaciones web modernas y mantenibles. El Concurrent Renderer abre un nivel completamente nuevo de control sobre la UX que antes era imposible sin soluciones externas complicadas. React 18 with TypeScript is the ideal combination for building modern, maintainable web applications. The Concurrent Renderer opens a completely new level of UX control that was previously impossible without complex external tooling.

Si buscas un desarrollador con experiencia real en React 18 + TypeScript, contáctame aquí. Trabajo de forma remota para clientes en Latinoamérica, España y Estados Unidos. Looking for a developer with real-world React 18 + TypeScript experience? Contact me here. I work remotely for clients across Latin America, Spain and the United States.

← Volver al blog← Back to blog Siguiente: API REST con Node.js →Next: REST API with Node.js →

Servicios de desarrollo de software: Santiago Alexander Aguilar Torres

Soy Santiago Alexander Aguilar Torres, desarrollador Full-Stack colombiano con sede en Tunja, Boyacá. Desarrollo aplicaciones web, plataformas móviles con Flutter y React Native, servicios backend con Node.js y Spring Boot, e infraestructura Linux VPS con Docker.

Disponible para roles de ingeniería y proyectos técnicos directos. Respuesta en menos de 24 horas.

Tecnologías y especialidades

Investigación y ponencias

Ponente en más de 6 congresos internacionales de ingeniería en Colombia: TEINCO 2025, CIISS 2025, TEINCO 2024, ENIIU 2024, Ci3S 2024. Co-investigador en proyectos de transporte urbano con validación offline y plataformas universitarias.

Disponibilidad y contacto

Disponible para trabajo remoto desde Colombia en roles Full-Stack Developer, Backend Developer y Freelance. Clientes en Colombia, Latinoamérica y España. Email: santiagoaguilart0@gmail.com. LinkedIn: santiagoaguilartorres-fullstack. WhatsApp: +57 314 256 6364.

—