Busca en todas las páginas de la documentación
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥
# Instala el compilador y su plugin de Babel
npm install -D babel-plugin-react-compiler
npm install -D react-compiler-healthcheck # opcional: verifica compatibilidad// babel.config.js
module.exports = {
plugins: [
["babel-plugin-react-compiler", {
// target por defecto es "19" para React 19
}],
],
};// next.config.js (Next.js 15+)
module.exports = {
experimental: {
reactCompiler: true,
},
};Cuándo usarlo: Habilita React Compiler en cualquier proyecto de React 19 para optimizar automáticamente los re-renderizados. Reemplaza la necesidad de useMemo, useCallback y React.memo en la gran mayoría de casos.
// Antes: Memoización manual en todas partes
import { useMemo, useCallback, memo } from "react";
type Todo = { id: string; text: string; completed: boolean };
const TodoItem = memo(function TodoItem({
todo,
onToggle,
}: {
todo: Todo;
onToggle: (id: string) => void;
}) {
return (
<li>
<input
type="checkbox"
checked={todo.completed}
onChange={() => onToggle(todo.id)}
/>
{todo.text}
</li>
);
});
function TodoList({ todos }: { todos: Todo[] }) {
const [filter, setFilter] = useState<"all" | "active" | "completed">("all");
const filteredTodos = useMemo(() => {
switch (filter) {
case "active": return todos.filter((t) => !t.completed);
case "completed": return todos.filter((t) => t.completed);
default: return todos;
}
}, [todos, filter]);
const handleToggle = useCallback((id: string) => {
// lógica de alternar
}, []);
const stats = useMemo(() => ({
total: todos.length,
active: todos.filter((t) => !t.completed).length,
completed: todos.filter((t) => t.completed).length,
}), [todos]);
return (
<div>
<p>{stats.active} items left</p>
<ul>
{filteredTodos.map((todo) => (
<TodoItem key={todo.id} todo={todo} onToggle={handleToggle} />
))}
</ul>
</div>
);
}// Después: Con React Compiler -- no se necesita memoización manual
import { useState } from "react";
type Todo = { id: string; text: string; completed: boolean };
function TodoItem({
todo,
onToggle,
}: {
todo: Todo;
onToggle: (id: string) => void;
}) {
return (
<li>
<input
type="checkbox"
checked={todo.completed}
onChange={() => onToggle(todo.id)}
/>
{todo.text}
</li>
);
}
function TodoList({ todos }: { todos: Todo[] }) {
const [filter, setFilter] = useState<"all" | "active" | "completed">("all");
const filteredTodos = (() => {
switch (filter) {
case "active": return todos.filter((t) => !t.completed);
case "completed": return todos.filter((t) => t.completed);
default: return todos;
}
})();
function handleToggle(id: string) {
// lógica de alternar
}
const stats = {
total: todos.length,
active: todos.filter((t) => !t.completed).length,
completed: todos.filter((t) => t.completed).length,
};
return (
<div>
<p>{stats.active} items left</p>
<ul>
{filteredTodos.map((todo) => (
<TodoItem key={todo.id} todo={todo} onToggle={handleToggle} />
))}
</ul>
</div>
);
}Lo que esto demuestra:
useMemo, useCallback y React.memo para evitar re-renderizados innecesariosuseMemo, useCallback y React.memo donde sea apropiado.target: "17" o target: "18" e instala el paquete react-compiler-runtime."use no memo" en la parte superior de una función para rechazar un componente o hook específico de la optimización del compilador.Despliegue gradual con modo opt-in:
// babel.config.js -- solo compila archivos con directiva "use memo"
module.exports = {
plugins: [
["babel-plugin-react-compiler", {
compilationMode: "annotation", // solo compila funciones con "use memo"
}],
],
};// Solo este componente es compilado
function OptimizedList({ items }: { items: string[] }) {
"use memo";
return (
<ul>
{items.map((item) => (
<li key={item}>{item}</li>
))}
</ul>
);
}Rechazar un componente específico:
function LegacyComponent({ data }: { data: any }) {
"use no memo";
// Este componente no será optimizado por el compilador
// Útil para código que intencionalmente rompe las reglas de React
externalMutableStore.value = data;
return <div>{data.label}</div>;
}Verificación de salud antes de adoptar:
# Ejecuta la verificación de salud para ver qué tan compatible es tu base de código
npx react-compiler-healthcheck --verbosePlugin ESLint para validación de reglas:
npm install -D eslint-plugin-react-compiler// eslint.config.js
import reactCompiler from "eslint-plugin-react-compiler";
export default [
{
plugins: { "react-compiler": reactCompiler },
rules: {
"react-compiler/react-compiler": "error",
},
},
];"use memo" y "use no memo" son directivas de literal de cadena (como "use strict") y no necesitan declaraciones de tipo.console.log(Date.now()) o modificar variables externas durante el renderizado puede producir resultados obsoletos cuando el compilador almacena en caché la salida. Solución: Mueve efectos secundarios a useEffect o manejadores de eventos.useSyncExternalStore para estado mutable externo.eslint-plugin-react-compiler para capturar problemas y verifica la salida de compilación del compilador para componentes omitidos.compilationMode: "annotation" para compilar solo componentes opt-in durante la migración.| Enfoque | Cuándo elegir |
|---|---|
| React Compiler | Predeterminado para proyectos de React 19 -- optimización automática, sin esfuerzo |
useMemo / useCallback manual | React 18 o cuando necesitas control explícito sobre qué se memoiza |
React.memo | React 18 o para componentes de clase que el compilador no maneja |
| Million.js | Compilador alternativo enfocado en optimización de diffing de DOM virtual |
| División manual de componentes | Aislando subárboles costosos cuando el compilador o memoización es insuficiente |
Directiva "use no memo" | Rechazando componentes específicos de la optimización del compilador |
useMemo, useCallback y React.memo manual en la mayoría de casos// next.config.js
module.exports = {
experimental: {
reactCompiler: true,
},
};Para proyectos que no son Next.js, instala babel-plugin-react-compiler y añádelo a tu configuración de Babel.
eslint-plugin-react-compiler para detectar qué componentes se están omitiendo y por quéfunction LegacyComponent({ data }) {
"use no memo";
// Este componente no será optimizado
externalStore.value = data;
return <div>{data.label}</div>;
}La directiva "use no memo" se coloca en la parte superior del cuerpo de la función.
// babel.config.js
module.exports = {
plugins: [
["babel-plugin-react-compiler", {
compilationMode: "annotation",
}],
],
};Luego añade "use memo" en la parte superior de las funciones que quieras compilar. Solo se optimizan las funciones anotadas.
npx react-compiler-healthcheck --verboseEsto escanea tu base de código e reporta qué componentes siguen las reglas de React y cuáles pueden causar problemas.
target: "17" o target: "18" en la configuración del pluginreact-compiler-runtimeconsole.log(Date.now()) durante el renderizado pueden producir resultados obsoletosuseEffect o manejadores de eventos donde pertenecenuseSyncExternalStore para estado mutable externo para que React pueda rastrear cambios"use memo" y "use no memo" son directivas de literal de cadena y no necesitan declaraciones de tipocompilationMode: "annotation" para compilar solo componentes opt-in durante una migración incrementalRevisado por Chris St. John·Última actualización: 7 jul 2026
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥