← React: componentes, estado e decisões de interface
01 / 10 · 60 MIN

Componentes, props e renderização pura

Construir componentes web que recebem dados e descrevem uma interface sem alterar as entradas. Interpretar JSX, composição e a diferença entre render e commit.

Ler o contrato de um componente

Um componente função recebe entradas e devolve uma descrição da interface. Em JSX, OrderSummary iniciado por maiúscula referencia a função do exemplo; section e p identificam elementos nativos. O nome do ficheiro e o texto mostrado não substituem esta distinção.

Antes de analisar uma página, escreve o contrato: que props chegam, quais são opcionais e que conteúdo é devolvido. Aqui orders é obrigatório e cada objeto contém um identificador, cliente e total numérico. Não se pode inferir desse exemplo que qualquer resposta de uma API tenha esse formato.

A validação dos dados na fronteira pertence ao contrato da aplicação. Conhecimentos de funções, arrays e objetos são pré-requisitos de JavaScript; a aula centra-se no uso dessas entradas por React.

JSX e agrupamento sem um contentor adicional

JSX é uma sintaxe usada para descrever a saída; não é uma string de HTML a inserir automaticamente. Fecha as tags e usa as propriedades previstas, como className. Quando a expressão devolve elementos adjacentes, um Fragment escrito como <>...</> permite agrupá-los sem acrescentar um elemento contentor ao DOM.

Um div sem atributos continua a ser um elemento; uma regra CSS que altere a apresentação também não o elimina do DOM. Escolhe um section quando queres realmente uma secção e uma estrutura semântica apropriada, como no exemplo, em vez de acrescentar um contentor só para satisfazer a sintaxe.

O Fragment resolve o agrupamento, mas não cria por si um título acessível nem define a relação entre controlos.

Props, defaults e dados que evoluem

As props são um snapshot das entradas deste render. Readonly significa que o filho não deve alterar os valores recebidos; não significa que o pai esteja impedido de fornecer outros valores no render seguinte. Se o pai substituir a lista de encomendas, o resumo calcula o total dessa nova lista.

O default currency = EUR aplica-se quando a prop falta ou vale undefined. Não substitui null, zero ou uma string vazia. Por isso, um default não é uma política completa de validação.

Ao investigar uma moeda em branco, começa por distinguir ausência da prop, null explícito e uma string vazia. Escolhe depois se o contrato deve rejeitar esses dados, normalizá-los na fronteira ou permitir deliberadamente essa apresentação.

Composição através de children

Panel recebe um título e conteúdo aninhado. React fornece esse conteúdo pela prop children; Panel escolhe onde o inclui no JSX. Se devolver apenas uma section vazia, os parágrafos do pai não aparecem nessa saída.

Esta composição permite usar a mesma moldura para um resumo, um aviso ou outro conteúdo, sem fazer Panel conhecer os detalhes de cada caso. Evita procurar o nome de um filho numa variável global ou usar uma classe CSS como suposto mecanismo de inserção.

O contrato fica mais claro quando a moldura assume a responsabilidade pela sua estrutura e o chamador fornece o conteúdo. Uma prop que é uma função callback também exige ligação explícita; a aula seguinte aplica essa ideia aos eventos.

Pureza e propriedade dos objetos

Renderizar não deve alterar objetos que existiam antes da chamada nem depender de alterações num contador global. O exemplo calcula total e names a partir de orders, sem modificar o array nem as encomendas. Criar um array local novo e preenchê-lo durante esta chamada pode ser compatível com pureza; alterar o array recebido não é a mesma operação.

Para ordenar a apresentação, uma cópia como [...orders].sort(compare) protege a ordem do array original quando compare é puro. Essa cópia é superficial: não autoriza escrever nos objetos internos. Ao rever código, acompanha cada referência e pergunta se o objeto foi criado nesta chamada ou pertence ao pai, a outro componente ou a um módulo partilhado.

Render, commit e efeitos observáveis

React pode voltar a calcular uma interface antes de aplicar alterações. A fase de render determina a descrição; no commit são aplicadas as mudanças necessárias ao DOM. Um registo de chamada do componente não prova que todos os elementos tenham sido recriados, nem prova que nada mudou.

Também não deve desencadear uma operação externa irreversível. Se o requisito é enviar uma encomenda após confirmação, associa esse envio ao handler dessa interação. Não uses a frequência de render como contador de submissões.

Effects servem para sincronização com sistemas externos quando necessária; mover indiscriminadamente um envio para um Effect não demonstra correspondência com a confirmação do utilizador. A identidade dos componentes e os limites de preservação de estado são tratados numa aula posterior.

Revisão orientada pelo contrato

Num painel com números de encomenda instáveis, verifica primeiro se o identificador vem dos dados persistentes ou de uma contagem de renders. Um contador global mistura a identidade de negócio com trabalho de apresentação que pode repetir-se.

Num cartão que aprova uma encomenda, procura depois a propriedade do estado: se o pai controla a lista, o filho pode comunicar onApprove(order.id), e o pai decidir a mudança e fornecer novas props. Não basta que uma mutação direta pareça funcionar após um render incidental.

Para fechar a revisão, regista entradas, saída pretendida, objetos que permanecem intactos e a interação responsável pelos efeitos. A avaliação pede escolher decisões e interpretar excertos; não exige executar o exemplo.

// Reading example: React web component; orders supplied by the parent.
// Each order has {id: string, customer: string, total: number}.
function Panel({title, children}) {
  return <section><h2>{title}</h2>{children}</section>;
}

export default function OrderSummary({orders, currency = 'EUR'}) {
  const total = orders.reduce((sum, order) => sum + order.total, 0);
  const names = orders.map(order => order.customer).join(', ');
  return (
    <Panel title="Orders awaiting review">
      <p>{orders.length} orders: {names}</p>
      <p>Total: {total} {currency}</p>
    </Panel>
  );
}
NA PRÁTICA

Com duas encomendas de 12 e 18, OrderSummary deriva 30 sem escrever nos objetos. Omitir currency usa EUR; passar null não ativa o default. Panel só mostra os parágrafos porque inclui children.

O exemplo omite formatação monetária e validação de dados para delimitar o contrato de render.

Armadilhas comuns

Confundir readonly com valor permanente; esperar que children apareça sem o renderizar; usar um contador global para gerar números de encomenda; assumir que um novo render implica recriar todos os nós DOM.

Tópicos relacionados: Eventos, snapshots de estado e filas de atualização · Estrutura do estado e identidade dos componentes

Leva esta ideia contigo

Um componente descreve a saída a partir de entradas atuais. As props podem mudar entre renders, mas o componente não as altera. Composição explícita e cálculo puro permitem repetir o trabalho sem modificar dados exteriores.

Criar conta

Referência: Defining components · React 19.3.0; JSX