Functional Component — es una forma de crear componentes de React usando funciones JavaScript normales, que se convirtió en el estándar después del lanzamiento de React 16.8 y la introducción de los hooks. Los componentes funcionales aceptan props y devuelven elementos React sin requerir herencia de React.Component. Según React, 2024, el 97% de los nuevos componentes en el ecosistema React se escriben como funciones.
Puntos Clave
Functional Component es un componente de React definido como una función que acepta un objeto props y devuelve un elemento React. Antes de React 16.8, estos componentes se llamaban stateless porque no podían gestionar estado interno.
Con la introducción de los hooks en React 16.8 (febrero de 2019), los componentes funcionales obtuvieron acceso al estado (useState), efectos secundarios (useEffect), contexto (useContext) y referencias (useRef). El término “stateless” está obsoleto — los componentes funcionales modernos gestionan el estado completamente.
React recomienda oficialmente los componentes funcionales como la forma principal de crear componentes. Toda la documentación en react.dev, ejemplos, tutoriales y nuevas APIs (Server Components, Actions) están construidos sobre el enfoque funcional. Los componentes de clase no se han eliminado, pero las nuevas funciones de React solo están disponibles a través de hooks.
El componente funcional más simple es una función que devuelve JSX. Acepta props como argumento, no requiere constructor, llamada a super ni enlace de this. Los props son accesibles directamente a través del argumento de la función — no se necesita this.props.
// Functional component without state
function Greeting({ name }) {
return <h1>Hello, {name}!</h1>;
}
// Arrow function (common variant)
const Greeting = ({ name }) => (
<h1>Hello, {name}!</h1>
);
Para agregar estado, use useState. El hook devuelve una tupla de dos valores: el estado actual y una función setter. A diferencia de this.setState en clases, useState reemplaza el valor por completo en lugar de fusionarlo con el anterior.
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Increment
</button>
</div>
);
}
Los hooks son la base del React moderno. Cada hook resuelve una tarea específica: useState — estado, useEffect — efectos secundarios, useContext — acceso al contexto, useRef — referencias a elementos DOM, useCallback y useMemo — memoización.
useEffect reemplaza componentDidMount, componentDidUpdate y componentWillUnmount a la vez. El primer argumento es un callback con el efecto, el segundo es un array de dependencias. Si el array está vacío, el efecto se ejecuta una vez después del montaje. Si se especifican dependencias, se ejecuta cuando cualquiera de ellas cambia.
import React, { useState, useEffect } from 'react';
function UserData({ userId }) {
const [user, setUser] = useState(null);
useEffect(() => {
let cancelled = false;
fetch(`/api/users/${userId}`)
.then(res => res.json())
.then(data => {
if (!cancelled) setUser(data);
});
// Cleanup - analog of componentWillUnmount
return () => { cancelled = true; };
}, [userId]); // Dependency
return <div>{user?.name}</div>;
}
La principal ventaja de los componentes funcionales es la reutilización de lógica mediante hooks personalizados. Mientras que en un componente de clase la lógica se duplicaba entre componentDidMount y componentDidUpdate, en un componente funcional se extrae en una función separada con el prefijo use. Los hooks personalizados son la alternativa principal a HOC y render props.
React recomienda la composición en lugar de la herencia para la reutilización de código entre componentes. Los componentes funcionales son ideales para la composición: un componente puede contener varios otros, pasándoles props y children.
El patrón children — cuando un componente recibe elementos hijos a través del prop children — se implementa de forma natural: function Layout({ children }). El equivalente de los slots de Vue se implementa mediante props de componentes con nombre: function Page({ header, sidebar, content }).
La herencia apenas se usa en React. Incluso los componentes de clase, que técnicamente soportan extends, raramente forman jerarquías de más de un nivel. Los componentes funcionales con composición cubren completamente las necesidades de reutilización de código sin herencia.
Los componentes funcionales vienen con mecanismos de optimización incorporados. React.memo — el equivalente de PureComponent para funciones: evita el re-renderizado si los props no han cambiado (comparación superficial). useMemo almacena en caché los resultados de los cálculos entre renders.
import React, { useMemo } from 'react';
// React.memo - memoize component
const ExpensiveList = React.memo(({ items }) => {
return <ul>
{items.map(item =>
<li key={item.id}>{item.name}</li>
)}
</ul>;
});
// useMemo - caching result
function Dashboard({ transactions }) {
const summary = useMemo(() => {
return transactions.reduce((acc, t) => acc + t.amount, 0);
}, [transactions]);
return <p>Total: {summary}</p>;
}
useCallback memoiza las funciones callback para que no se recreen en cada render. Esto es crítico al pasar funciones a componentes hijos envueltos en React.memo: sin useCallback, el componente hijo se re-renderizará cada vez porque la referencia a la función cambia.
La diferencia entre los enfoques va más allá de la sintaxis. Los componentes funcionales son closures: el estado y los efectos están vinculados a un render específico. Los componentes de clase usan this: el estado siempre se obtiene de this.state, que puede estar desactualizado cuando se ejecuta un callback asíncrono.
| Aspecto | Funcional | Clase |
|---|---|---|
| Estado | useState (aislado) | this.state + this.setState |
| Efectos | useEffect con dependencias | componentDidMount + componentDidUpdate |
| Contexto | useContext | Context.Consumer o static contextType |
| Optimización | React.memo + useMemo | PureComponent + shouldComponentUpdate |
| Reutilización | Hooks personalizados | HOC / Render props |
| this | Ninguno | bind en constructor |
Los componentes funcionales proporcionan un flujo de ejecución lineal. En un componente de clase, la lógica relacionada a menudo está dispersa en múltiples métodos de ciclo de vida. Por ejemplo, una suscripción a WebSocket se configura en componentDidMount y se elimina en componentWillUnmount. En un componente funcional, ambas operaciones están en un único useEffect con una función de limpieza de retorno.
TypeScript funciona más naturalmente con componentes funcionales que con clases. Tipado de props — una interfaz para el argumento de la función. El tipo de retorno es JSX.Element o ReactNode. useState infiere automáticamente el tipo del valor inicial.
import React, { useState } from 'react';
interface ButtonProps {
label: string;
variant?: 'primary' | 'secondary';
onClick: () => void;
}
const Button: React.FC<ButtonProps> =
({ label, variant = 'primary', onClick }) => (
<button
className={`btn btn-${variant}`}
onClick={onClick}
>
{label}
</button>
);
TypeScript moderno permite tipar useReducer con tipos union discriminados, Genéricos en hooks personalizados y validación estricta de children mediante React.PropsWithChildren. Los componentes funcionales con TypeScript proporcionan seguridad de tipos completa sin abstracciones adicionales.
Preguntas Frecuentes
Los componentes funcionales son más simples: sin constructor, bind, this ni métodos de ciclo de vida dispersos. Los hooks permiten agrupar la lógica relacionada. React invierte recursos en desarrollar hooks, no clases. Server Components y nuevas funciones solo están disponibles en funciones.
Sí, a través de useEffect con un temporizador dentro y una función de limpieza para clearInterval. Preste atención al closure: si está incrementando un contador, use la forma funcional de setState: setCount(c => c + 1) para no depender del valor antiguo en el closure.
Use useRef para almacenar el valor anterior. Actualice la ref en useEffect después de cada render. Un hook personalizado usePrevious ayuda para una comparación limpia: const prev = usePrevious(value);
React.memo es un HOC para memoizar un componente completo: evita el re-renderizado si los props no han cambiado. useMemo es un hook para memoizar un valor específico dentro de un componente: almacena en caché el resultado de una función entre renders mediante un array de dependencias.
La forma más simple es useState con inicialización desde props + useEffect con dependencia de props para sincronización. Para casos raros, React recomienda usar una key para forzar la recreación del componente cuando los datos de entrada cambian.
Resumen
Desarrollaremos una aplicación móvil llave en mano
IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.
Lea también