Um componente React é uma função JavaScript que retorna JSX: uma parte reutilizável da UI, como um botão, um card ou uma página inteira. Você o usa como uma tag HTML, <Profile />, e o React chama a função para descobrir o que colocar na tela. Aplicações são construídas colocando componentes dentro de outros componentes.
App renderiza Profile duas vezes, e cada Profile renderiza um Avatar. Mude as iniciais dentro de Avatar e os dois perfis são atualizados, porque compartilham uma única definição. Por enquanto todas as pessoas desta lista são iguais; a próxima página, props, mostra como passar para cada cópia os próprios dados.
Escrevendo um componente
Um componente de função tem dois requisitos:
- O nome começa com letra maiúscula:
Profile, nãoprofile. - Ele retorna algo que o React consegue renderizar: JSX, uma string, um número,
null(não renderiza nada) ou um array dessas coisas.
function Welcome() {
return <h1>Welcome back</h1>;
}
// Arrow functions work the same way
const Welcome = () => <h1>Welcome back</h1>;
Quando o JSX ocupa várias linhas, envolva-o em parênteses depois do return. Sem eles, um return seguido de quebra de linha retorna undefined, e tudo o que vem depois é ignorado.
Por que o nome precisa de maiúscula
O JSX olha a primeira letra de uma tag. Minúscula significa um elemento HTML embutido, então <div> continua <div>. Maiúscula significa "uma variável no escopo", então <Profile /> chama sua função Profile. Dê um nome em minúsculas a um componente e o React cria, no lugar, um elemento HTML desconhecido com esse nome:
A segunda linha mostra só o rótulo, e o console só mostra Greeting ran. O React colocou uma tag <greeting> vazia na página e nunca chamou a função em minúsculas. Um build de desenvolvimento também avisa que The tag <greeting> is unrecognized in this browser; a prévia roda como um build de produção, então você só vê o texto faltando. Renomeie a função para Greetings e a tag para <Greetings /> para corrigir.
Compondo componentes
Componentes foram feitos para serem aninhados. Uma página é uma árvore: App no topo, depois as partes de layout, depois partes menores até chegar a botões isolados. Cada componente só conhece as partes que renderiza diretamente, então você consegue pensar em um de cada vez.
Cada LikeButton tem o próprio estado, então curtir um post não mexe nos outros. Para adicionar um botão de compartilhar em todos os posts, você o escreve uma vez e adiciona <ShareButton /> dentro de Post.
Quando dividir um componente
Não existe regra fixa, mas alguns sinais dizem que uma parte merece um componente próprio: a mesma marcação aparece em dois lugares, um trecho do JSX tem estado próprio (como o botão de curtir acima), ou a função cresceu tanto que você precisa rolar para ver o return. Dividir nesses pontos mantém cada componente pequeno o bastante para ler em uma tela. Dividir cedo demais custa pouco: um componente é só uma função, então juntar dois de volta é fácil.
Exportando e importando componentes
Os editores aqui têm um único arquivo, mas um projeto real coloca componentes em arquivos próprios. Um arquivo pode ter um export default e quantos exports nomeados quiser:
// Avatar.jsx
export default function Avatar({ initials }) {
return <div className="avatar">{initials}</div>;
}
// Badge.jsx
export function Badge({ label }) {
return <span className="badge">{label}</span>;
}
export function NewBadge() {
return <Badge label="new" />;
}
// Profile.jsx
import Avatar from './Avatar.jsx';
import { Badge, NewBadge } from './Badge.jsx';
export default function Profile() {
return (
<div>
<Avatar initials="AL" />
<Badge label="admin" />
<NewBadge />
</div>
);
}
Um export default pode ser importado com qualquer nome; um export nomeado é importado entre chaves com o nome exato. As equipes costumam escolher um estilo e manter. Os nomes de arquivo normalmente batem com o componente: Avatar.jsx exporta Avatar.
Mantenha os componentes puros
O React espera que um componente se comporte como uma função pura enquanto renderiza: as mesmas props e o mesmo estado dão o mesmo JSX, e a renderização não muda nada que já existia antes de ela rodar. O React pode renderizar um componente muitas vezes, em momentos que você não controla, então um componente que altera variáveis externas durante a renderização produz um resultado diferente a cada vez.
As xícaras impuras começam em 1, 2, 3. Clique no botão: nada mudou nos convidados, mas a lista impura agora mostra 4, 5, 6, porque cada renderização somou na variável compartilhada guest. As xícaras puras recebem o número pelas props e continuam corretas. Em desenvolvimento, o Strict Mode renderiza cada componente duas vezes para expor exatamente esse tipo de bug; a prévia roda como um build de produção, então aqui o desvio só aparece quando você renderiza de novo.
Mudar coisas não é problema, só não durante a renderização. Atualize o estado em event handlers e converse com o mundo externo (timers, assinaturas, o título do documento) em efeitos.
Componentes vs elementos
O componente é a função, Profile. Um elemento é o que o JSX cria quando você escreve <Profile />: um pequeno objeto dizendo "renderize Profile com estas props". O React cria elementos, chama os componentes que eles nomeiam e transforma o resultado em DOM. Você nunca chama um componente diretamente como Profile(); você escreve <Profile /> e deixa o React chamá-lo, para que ele possa acompanhar o estado e o lugar dele na árvore.
Esse lugar importa. Este exemplo define um componente dentro de outro componente, um erro comum:
Digite algo e depois clique no botão: seu texto desaparece. Cada renderização de App cria uma função NameField nova, então o React vê um tipo de componente diferente naquele lugar e descarta o antigo junto com o estado. Mova NameField para cima de App, no nível superior do arquivo, e o texto sobrevive a todos os cliques. A página sobre renderização explica como o React decide o que manter.
Componentes de função e componentes de classe
Antes de os hooks chegarem no React 16.8, componentes que precisavam de estado eram escritos como classes:
import { Component } from 'react';
class Welcome extends Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
Componentes de classe ainda funcionam no React 19, e você vai encontrá-los em códigos mais antigos e em error boundaries, que ainda exigem uma classe. Código novo usa componentes de função com hooks como useState e useEffect, que fazem o mesmo trabalho com menos código. A página de componentes de classe relaciona cada recurso de classe ao hook correspondente.
Perguntas frequentes
O que é um componente no React?
Um componente é uma parte reutilizável da UI escrita como uma função JavaScript que retorna JSX. Você o usa como uma tag HTML, <Profile />, e o React chama a função para descobrir o que desenhar.
Por que o nome de um componente React precisa começar com letra maiúscula?
O JSX usa a primeira letra para decidir o que é uma tag. Uma tag em minúsculas como <profile /> é tratada como um elemento HTML chamado profile, e sua função nunca é chamada. Uma tag com maiúscula como <Profile /> se refere ao seu componente.
Qual é a diferença entre componentes de função e de classe?
Os dois descrevem UI. Componentes de função são funções comuns e usam hooks para estado e efeitos; componentes de classe estendem React.Component e usam métodos como render e componentDidMount. Código novo usa componentes de função.
O que é um componente puro no React?
Um componente puro retorna o mesmo JSX para as mesmas props e o mesmo estado e não muda nada fora de si enquanto renderiza. O React conta com isso para renderizar componentes quantas vezes precisar sem surpresas.
Posso definir um componente dentro de outro componente?
Evite. Um componente definido dentro de outro é uma nova função a cada renderização, então o React o trata como um componente diferente a cada vez e reinicia o estado dele. Defina componentes no nível superior do arquivo.