Functional Component — é uma maneira de criar componentes React usando funções JavaScript comuns, que se tornou o padrão após o lançamento do React 16.8 e a introdução dos hooks. Componentes funcionais aceitam props e retornam elementos React sem exigir herança de React.Component. De acordo com React, 2024, 97% dos novos componentes no ecossistema React são escritos como funções.
Pontos Principais
Functional Component é um componente React definido como uma função que aceita um objeto props e retorna um elemento React. Antes do React 16.8, esses componentes eram chamados de stateless porque não conseguiam gerenciar estado interno.
Com a introdução dos hooks no React 16.8 (fevereiro de 2019), componentes funcionais ganharam acesso a estado (useState), efeitos colaterais (useEffect), contexto (useContext) e refs (useRef). O termo “stateless” está obsoleto — componentes funcionais modernos gerenciam estado completamente.
React recomenda oficialmente componentes funcionais como a forma principal de criar componentes. Toda a documentação em react.dev, exemplos, tutoriais e novas APIs (Server Components, Actions) são construídos na abordagem funcional. Componentes de classe não foram removidos, mas novos recursos do React estão disponíveis apenas através de hooks.
O componente funcional mais simples é uma função que retorna JSX. Ele aceita props como argumento, não requer construtor, chamada super ou vinculação de this. Props são acessíveis diretamente através do argumento da função — sem 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 adicionar estado, use useState. O hook retorna uma tupla de dois valores: o estado atual e uma função setter. Diferente do this.setState baseado em classe, useState substitui o valor inteiramente em vez de mesclá-lo com o 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>
);
}
Hooks são a base do React moderno. Cada hook resolve uma tarefa específica: useState — estado, useEffect — efeitos colaterais, useContext — acesso ao contexto, useRef — referências a elementos DOM, useCallback e useMemo — memoização.
useEffect substitui componentDidMount, componentDidUpdate e componentWillUnmount ao mesmo tempo. O primeiro argumento é um callback com o efeito, o segundo é um array de dependências. Se o array estiver vazio, o efeito é executado uma vez após a montagem. Se dependências forem especificadas, executa quando qualquer uma delas mudar.
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>;
}
A principal vantagem dos componentes funcionais é a reutilização de lógica através de hooks personalizados. Enquanto em um componente de classe a lógica era duplicada entre componentDidMount e componentDidUpdate, em um componente funcional ela é extraída para uma função separada com o prefixo use. Hooks personalizados são a alternativa principal a HOC e render props.
React recomenda composição em vez de herança para reutilização de código entre componentes. Componentes funcionais são ideais para composição: um componente pode conter vários outros, passando props e children.
O padrão children — quando um componente recebe elementos filhos através da prop children — é implementado naturalmente: function Layout({ children }). O análogo de slots do Vue é implementado através de props de componentes nomeados: function Page({ header, sidebar, content }).
Herança é raramente usada em React. Mesmo componentes de classe, que tecnicamente suportam extends, raramente formam hierarquias mais profundas que um nível. Componentes funcionais com composição cobrem completamente as necessidades de reutilização de código sem herança.
Componentes funcionais vêm com mecanismos de otimização embutidos. React.memo — o equivalente de PureComponent para funções: previne re-renderização se props não mudaram (comparação superficial). useMemo armazena em cache resultados de cálculos entre renderizações.
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 funções callback para que não sejam recriadas em cada renderização. Isso é crítico ao passar funções para componentes filhos envolvidos em React.memo: sem useCallback, o componente filho será re-renderizado toda vez porque a referência da função muda.
A diferença entre as abordagens vai além da sintaxe. Componentes funcionais são closures: estado e efeitos estão vinculados a uma renderização específica. Componentes de classe usam this: o estado é sempre obtido de this.state, que pode estar desatualizado quando um callback assíncrono executa.
| Aspecto | Funcional | Classe |
|---|---|---|
| Estado | useState (isolado) | this.state + this.setState |
| Efeitos | useEffect com dependências | componentDidMount + componentDidUpdate |
| Contexto | useContext | Context.Consumer ou static contextType |
| Otimização | React.memo + useMemo | PureComponent + shouldComponentUpdate |
| Reutilização | Hooks personalizados | HOC / Render props |
| this | Nenhum | bind no construtor |
Componentes funcionais fornecem um fluxo de execução linear. Em um componente de classe, a lógica relacionada é frequentemente espalhada por vários métodos de ciclo de vida. Por exemplo, uma assinatura WebSocket é configurada em componentDidMount e removida em componentWillUnmount. Em um componente funcional, ambas as operações estão em um único useEffect com uma função de limpeza de retorno.
TypeScript funciona mais naturalmente com componentes funcionais do que com classes. Tipagem de props — uma interface para o argumento da função. O tipo de retorno é JSX.Element ou ReactNode. useState infere automaticamente o tipo do 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 com tipos union discriminados, Genéricos em hooks personalizados e validação estrita de children através de React.PropsWithChildren. Componentes funcionais com TypeScript fornecem segurança de tipos completa sem abstrações adicionais.
Perguntas Frequentes
Componentes funcionais são mais simples: sem construtor, bind, this ou métodos de ciclo de vida dispersos. Hooks permitem agrupar lógica relacionada. React investe recursos no desenvolvimento de hooks, não de classes. Server Components e novos recursos estão disponíveis apenas em funções.
Sim, através de useEffect com um temporizador interno e uma função de limpeza para clearInterval. Preste atenção ao closure: se você estiver incrementando um contador, use a forma funcional de setState: setCount(c => c + 1) para não depender do valor antigo no closure.
Use useRef para armazenar o valor anterior. Atualize a ref no useEffect após cada renderização. Um hook personalizado usePrevious ajuda para comparação limpa: const prev = usePrevious(value);
React.memo é um HOC para memoizar um componente inteiro: previne re-renderização se props não mudaram. useMemo é um hook para memoizar um valor específico dentro de um componente: armazena em cache o resultado de uma função entre renderizações por um array de dependências.
A maneira mais simples é useState com inicialização a partir de props + useEffect com dependência de props para sincronização. Para casos raros, React recomenda usar uma key para forçar a recriação do componente quando os dados de entrada mudam.
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.
Leia também