Pular para o conteúdo
murad.guide

Referência Essencial da Web

Capítulo 16

Frameworks e React

4 min de leitura 700 palavras 1 gravura

Trabalhe numa cópia da pasta inicio/ desta etapa. Ela já abre ou executa com as instruções do README. Leia o código, mude uma coisa e anote sua previsão antes de recarregar. Compare com a referência na pasta da etapa. Se nada mudar, confira a extensão do arquivo, o arquivo salvo e o caminho aberto. Blocos adicionais do capítulo são experiências separadas; a pasta de referência contém o programa completo desta etapa.

A Biblioteca da Ribeira é um acervo comunitário fictício no bairro da Ribeira, Recife. Neste capítulo a casa ganha uma lista de tarefas de catalogação. O exemplo usa React com Vite. Não use o gerador antigo create-react-app.

O exemplo está em pacote de exemplos/16-frameworks-e-react/. No terminal, nessa pasta: npm install e depois npm run dev. Abra http://127.0.0.1:5173/.

Ciclo: ler → copiar → mudar uma coisa → prever → recarregar → conferir.

O que você vai aprender

Por que framework

No JavaScript puro você cria elementos, cola ouvintes e atualiza o texto. Funciona. Quando a tela tem muitos cartões e estados, o código se espalha.

Um framework oferece um jeito de montar a interface em peças. React é um deles. Não é obrigatório para o site estático da Ribeira. Este capítulo mostra o recorte: uma lista pequena.

HTML e CSS continuam. O React gera a árvore. O navegador ainda pinta.

Não troque o site inteiro da biblioteca por React só porque o volume chegou. Use quando a interação crescer de verdade.

Vite, não o gerador antigo

Vite é a ferramenta que sobe o servidor de estudo e empacota os arquivos. Neste volume o projeto já está criado. Você não executa create-react-app.

package.json (trecho que importa):

{
  "scripts": {
    "dev": "vite --host 127.0.0.1 --port 5173",
    "build": "vite build"
  }
}

vite.config.js:

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
export default defineConfig({
  plugins: [react()],
  server: { host: "127.0.0.1", port: 5173 }
});

No terminal:

npm install
npm run dev -- --host 127.0.0.1

O -- --host 127.0.0.1 reforça o endereço se o script não trouxer o host. Só a sua máquina. A porta 5173 é a deste exemplo.

Erro comum: abrir o index.html do React com dois cliques. Sem o Vite, o src/main.jsx não resolve. Use o endereço http://127.0.0.1:5173/.

Componentes

Componente é uma função que devolve marcação. App é o componente principal. Você reutiliza a mesma peça com dados diferentes.

Um componente Tarefa e uma lista que reutiliza várias tarefas

src/main.jsx:

import React from "react";
import { createRoot } from "react-dom/client";
import App from "./App.jsx";
createRoot(document.getElementById("raiz")).render(<App />);

O HTML tem só <div id="raiz"></div>. O React desenha dentro.

Estado e eventos

Estado é o dado que, quando muda, a tela redesenha. useState guarda o texto do campo e a lista.

O arquivo src/App.jsx do exemplo:

import { useState } from "react";

export default function App() {
  const [texto, setTexto] = useState("");
  const [tarefas, setTarefas] = useState([
    { id: 1, nome: "Catalogar Maré Alta", feita: false }
  ]);
  function adicionar(evento) {
    evento.preventDefault();
    if (!texto.trim()) return;
    setTarefas([...tarefas, { id: Date.now(), nome: texto.trim(), feita: false }]);
    setTexto("");
  }
  return (
    <main>
      <h1>Tarefas da Ribeira</h1>
      <form onSubmit={adicionar}>
        <label htmlFor="nova">Nova tarefa</label>
        <input id="nova" value={texto} onChange={(e) => setTexto(e.target.value)} />
        <button type="submit">Adicionar</button>
      </form>
      <ul>
        {tarefas.map((item) => (
          <li key={item.id}>
            <label>
              <input
                type="checkbox"
                checked={item.feita}
                onChange={() =>
                  setTarefas(tarefas.map((t) => t.id === item.id ? { ...t, feita: !t.feita } : t))
                }
              />
              {item.nome}
            </label>
          </li>
        ))}
      </ul>
    </main>
  );
}

Não altere o array na marra. setTarefas recebe um array novo. key={item.id} identifica cada linha.

Mude uma coisa. Troque o texto inicial "Catalogar Maré Alta" por "Catalogar Caderno do Cais". Preveja a primeira linha. Salve. O Vite recarrega. Confira.

Acessibilidade no React

No JSX, class vira className. for do rótulo vira htmlFor. Sem htmlFor e id iguais, o clique no texto não foca o campo.

Caixa de tarefa mora dentro de <label>. Teclado: Tab até o campo, Enter envia o form. Não use div no papel de botão.

lang="pt-BR" continua no index.html. Viewport também.

Disco, 127.0.0.1 e publicação

Disco: os arquivos src/. Sem npm run dev, a lista não abre como app.

127.0.0.1:5173: teste local do Vite. Não é a internet.

Publicação seria npm run build e enviar a pasta dist. Este volume não pede publicação. Não cadastre pessoas reais na lista.

Atividades

  1. Por que este volume usa Vite e não o gerador create-react-app?
  2. O que acontece se você abrir o index.html do exemplo 16 pelo disco?
  3. Por que o rótulo usa htmlFor e não for no JSX?

Respostas comentadas

  1. O exemplo já nasce com Vite. É a ferramenta deste volume. create-react-app é o gerador antigo; não use aqui.
  2. O navegador não empacota o JSX. A raiz fica vazia ou o módulo falha. Precisa de npm run dev em 127.0.0.1.
  3. for é palavra reservada do JavaScript. No JSX o atributo HTML for se escreve htmlFor.

O arquivo completo

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

index.html

<!DOCTYPE html>
<html lang="pt-BR">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Tarefas da Ribeira</title>
  </head>
  <body>
    <div id="raiz"></div>
    <script type="module" src="/src/main.jsx"></script>
  </body>
</html>

vite.config.js

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
export default defineConfig({
  plugins: [react()],
  server: { host: "127.0.0.1", port: 5173 }
});