Pular para o conteúdo
murad.guide

Aplicações Web

Capítulo 2

React: componentes e JSX

3 min de leitura 506 palavras 1 gravura

Neste capítulo você vai criar o primeiro componente React do Ateliê com JSX via CDN. O projeto-fio é o Ateliê Boa Viagem, ateliê digital fictício em Boa Viagem, Recife.

Seu ponto de partida

Use o exemplo 02-react-componentes do pacote anexo e copie inicio/ para uma pasta de prática fora do original. A raiz do exemplo é a referência completa desta etapa.

Use servidor só em 127.0.0.1 quando o README do exemplo pedir HTTP local. Abrir ou testar não publica nada.

Como praticar

Leia → copie ou digite → mude uma coisa → preveja → salve → recarregue → confira. Restaure cada experiência antes da próxima. Faça as atividades antes de abrir as respostas comentadas.

Componente é uma função que devolve interface

No React, um componente descreve um pedaço da tela. JSX parece HTML dentro de JavaScript, mas vira chamadas de criação de elementos. Neste volume usamos React por CDN e Babel no navegador para estudar sem instalador.

Faça na sua cópia

Confira o trecho no contexto do exemplo antes de mudar.

function Cabecalho() {
  return <h1>Ateliê Boa Viagem</h1>;
}

Mude uma coisa e preveja

Altere o texto do h1 dentro do componente.

Anote o que espera observar antes de salvar e recarregar.

Recarregue e confira

A página mostra o novo título.

Se não acontecer

Confira se o script type é text/babel e se ReactDOM.createRoot aponta para #raiz.

Componente React do Ateliê

Props passam dados de fora para dentro

Props são argumentos. O pai envia; o filho lê. Não altere props diretamente dentro do filho.

Faça na sua cópia

Confira o trecho no contexto do exemplo antes de mudar.

function Oficina({ nome }) {
  return <article className="card"><h2>{nome}</h2></article>;
}

Mude uma coisa e preveja

Passe outra oficina como prop.

Anote o que espera observar antes de salvar e recarregar.

Recarregue e confira

O cartão mostra o novo nome.

Se não acontecer

Em JSX use className, não class.

Um erro comum: raiz ausente

Sem um elemento com id raiz, o React não monta. Outro erro comum é misturar vários roots sem intenção.

Faça na sua cópia

Confira o trecho no contexto do exemplo antes de mudar.

<div id="raiz"></div>

Mude uma coisa e preveja

Renomeie temporariamente o id e veja a falha no console.

Anote o que espera observar antes de salvar e recarregar.

Recarregue e confira

A interface some e o console aponta o elemento nulo. Restaure #raiz.

Se não acontecer

Abra as ferramentas do desenvolvedor (F12) na aba Console.

Atividades

Atividade 1

O que é um componente React em uma frase?

Atividade 2

Por que usamos className em JSX?

Atividade 3

Qual o papel da div#raiz?

Respostas comentadas

Resposta da atividade 1

Uma função (ou classe) que descreve um pedaço da interface.

Resposta da atividade 2

class é palavra reservada em JavaScript; JSX usa className.

Resposta da atividade 3

É o ponto do DOM onde o React monta a árvore da aplicação.

O arquivo completo

Referência do exemplo 02-react-componentes, reproduzida aqui para que você possa conferir sem sair da página.

styles.css

:root{--ink:#1a1a1a;--bg:#f7f4ef;--brand:#1f3a5f;--accent:#c45c26;--line:#d9d2c5;--focus:#0b57d0}
*{box-sizing:border-box}html{font-family:"Segoe UI",Tahoma,sans-serif;color:var(--ink);background:var(--bg)}
body{margin:0;line-height:1.5}a:focus-visible,button:focus-visible,input:focus-visible{outline:3px solid var(--focus);outline-offset:2px}
.skip{position:absolute;left:-999px}.skip:focus{left:1rem;top:1rem;z-index:10;background:#fff;padding:.5rem}
header,footer{background:var(--brand);color:#fff;padding:1rem 1.25rem}header a,footer a{color:#fff}
main{max-width:52rem;margin:0 auto;padding:1.25rem}h1{color:var(--brand);margin-top:0}
.card{background:#fff;border:1px solid var(--line);padding:1rem;margin:.75rem 0}
button{background:var(--accent);color:#fff;border:0;padding:.55rem 1rem;cursor:pointer}
.board{display:grid;grid-template-columns:repeat(3,4.5rem);gap:.4rem}
.square{width:4.5rem;height:4.5rem;font-size:1.5rem;background:#fff;border:2px solid var(--brand)}
label{display:block;margin:.5rem 0 .2rem;font-weight:600}
input,textarea{width:100%;max-width:28rem;padding:.45rem;border:1px solid var(--line)}
ul.nav{list-style:none;padding:0;display:flex;gap:1rem;flex-wrap:wrap;margin:0}
.status{font-weight:600;margin:.75rem 0}