Objeto: Introdução ao React
Principais termos técnicos abordados: React, ReactDOM, JavaScript, HTML
Requisitos para as instruções funcionarem: navegador e editor de texto instalados
Requisitos para compreensão das instruções: noções bem básicas de programação JavaScript e de HTML
Como ler essa receita: instruções, dentro dos passos da receita e que requerem ação sua no computador, estarão escritas em cor azul. Comentários sobre os passos estarão em fonte normal, cor preta. Comandos, código-fonte, termos técnicos ou configuração explícita, estarão com fonte diferenciada.
Observação: eventuais instruções de terminal serão comandos Linux. Adapte caso esteja usando outro sistema operacional
O React é uma biblioteca Javascript para front-end (vai rodar, em princípio, ao seio de um navegador Web) extremamente popular, open source e originalmente desenvolvida pelo então Facebook. Essa biblioteca, por vezes chamada de framework, vai ajudar enormemente a atualizar sua interface com o usuário (sua página web!) "reativamente" a mudanças nos modelos de dados sobre os quais ela se constrói. A ideia é a de que você se ocupe mais em manter esses modelos de dados - o "estado" da aplicação - atualizados (a partir de interações com o usuário ou com sistemas na Internet) e o React cuide em renderizar tão somente os pedaços de sua página (marcas HTML, essencialmente) que fazem uso desses dados.
Vamos começar a trabalhar com React nesta receita, mas levará algumas receitas a mais para entendermos sua "mágica".
Ao trabalho!
Crie um diretório react_example e, dentro deste, um subdiretório libs.
Baixe a biblioteca react.js e salve-a em react_intro/libs:
curl -L https://unpkg.com/react@17/umd/react.development.js > libs/react.js
Baixe a biblioteca react-dom.js e salve-a em react_intro/libs:
curl -L https://unpkg.com/react-dom@17/umd/react-dom.development.js > libs/react-dom.js
Salve em react_example um arquivo de nome index.html
Edite o index.html com o código a seguir:
<!DOCTYPE html>
<html>
<head>
<title>ReactZero</title>
</head>
<body>
<div id="app">
</div>
<script src="libs/react.js"></script>
<script src="libs/react-dom.js"></script>
<script>
</script>
</body>
</html>
No <div> logo abaixo do <body> o react vai renderizar a interface gráfica de nossa página. Na última marca <script> vamos dizer para o react fazer isso. As duas primeiras marcas <script> fazem a "importação" das bibliotecas do react de que precisaremos para nossas tarefas (há diversas outras "bibliotecas" no react). Se você teve dificuldade em fazer o download das bibliotecas, pode substituir as duas primeiras marcas script por:
<script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin></script>
Outrossim, o "@17" nas URL's acima refere-se à última versão do React 17 quando da produção deste material.
Dentro da última marca <script> (a vazia e sem atributos), acrescente o seguinte código:
ReactDOM.render(
React.createElement('h1', null, 'React!'),
document.getElementById('app')
);
O que está acontecendo aqui? Estamos chamando um método sobre um objeto (bem, vamos entender como um objeto), o ReactDOM. Esse método é o render().
Esse ReactDOM com esse método render foi carregado por aquela marca <script src="libs/react-dom.js"> e está disponível para o código JavaScript que você quiser escrever lá na terceira marca <script>
Esse método render() recebe 2 parâmetros: o primeiro é o elemento que devemos renderizar (construir, mostrar) algum elemento gráfico, o segundo é uma referência para onde devemos renderizar esse elemento gráfico.
O primeiro parâmetro está sendo produzido a partir de uma chamada a React.createElement('h1', null, 'React!'), e podemos pensar o React como um objeto importado através da marca <script src="libs/react.js"></script> (você pode abrir o arquivo e deverá achar algum "React" lá dentro, mas isso não é realmente importante).
O segundo parâmetro é obtido a partir de uma chamada a document.getElementById('app').
A chamada da função React.createElement('h1', null, 'React!') vai, como é fácil supor, produzir um objeto de interface gráfica do React que, por sua vez, é capaz de produzir o código HTML equivalente a <h1>React!</h1>. A função render vai pegar esse código HTML produzido por esse objeto e escrevê-lo (o código HTML) como filho da marca identificada pelo document.getElementById('app').
Salve o arquivo HTML, abra-o num navegador, e inspecione o código pelo seu navegador.
Você deverá ver algo assim na interface com o usuário...
...e algo assim no inspetor de código
- Carai, e por que não apagar todos aqueles scripts e escrever logo o <h1>React!</h1> abaixo do <div> se é esse o resultado final??? Que diferença faz essa burocracia toda?
A diferença é que, em usando a estratégia que usamos, os componentes do React vão cuidar de gerenciar os objetos DOM da página, suas atualizações etc.
E isso é muito bom, apesar de não ficar claro num primeiro exemplo.
Mas vamos brincar um pouco com o código.
Troque a chamada React.createElement('h1', null, 'React!') pela chamada React.createElement('h1', {id:'maria-prea'}, 'React!'). Salve novamente o arquivo, abra-o no navegador e inspecione o código.
A interface com o usuário continua exatamente a mesma, mas o código gerado mudou... um atributo id="maria-prea" foi acrescentado à marca <h1>.
Assim, ficamos sabendo que no segundo parâmetro do React.createElement() podemos especificar propriedades que irão fazer parte do código HTML gerado na renderização.
A ideia, por enquanto, é que a cada marca HTML que queiramos em nossa interface com o usuário, façamos uma chamada a React.createElement() dentro de um ReactDOM.render() e passando as propriedades que bem entendermos. Mas e como ficaria com uma marca dentro da outra e mais outra dentro da uma?
Troque a chamada a React.createElement('h1', {id:'maria-prea'}, 'React!') por
React.createElement(
'h1',
{id: 'my-heading'},
React.createElement(
'span',
null,
'React ',
React.createElement('em', null, 'é muito'),
),
' massa!'
)
Bem, se você não se perdeu no meio do caminho, seu arquivo HTML deve estar mais ou menos assim:
<!DOCTYPE html>
<html>
<head>
<title>ReactZero</title>
</head>
<body>
<div id="app">
</div>
<script src="libs/react.js"></script>
<script src="libs/react-dom.js"></script>
<script>
ReactDOM.render(
React.createElement(
'h1',
{id: 'my-heading'},
React.createElement(
'span',
null,
'React ',
React.createElement('em', null, 'é muito'),
),
' massa!'
),
document.getElementById("app"))
</script>
</body>
</html>
Salve, abra, inspecione...
A interface com o usuário deve estar assim... (note o itálico em "é muito")
... e o código gerado deve estar assim...
Com isso a gente pode perceber que, nas chamadas a React.createElement(), podemos passar vários parâmetros extras além daqueles 3 que tínhamos visto. O primeiro parâmetro é o nome da marca, o segundo as propriedades (como um objeto) e os demais parâmetros são o conteúdo da marca. No caso da primeira chamada a React.createElement(), temos dois "conteúdos" passados como parâmetro: um é o resultado de uma outra chamada a React.createElement(), o outro é o texto ' massa!'.
No caso da segunda chamada a React.createElement(), temos também dois "conteúdos" passados como parâmetro, além do 'span' que é o nome da marca e o null que representa as propriedades: um é o string 'React ', outro é uma nova chamada a React.createElement().
A ideia é que sempre que for aparecer uma nova marca a gente chame um React.createElement(). Quando o valor for "primitivo" (string, número etc.), a gente simplesmente passa o valor.
Desta forma, estas chamadas, umas dentro das outras, definem uma hierarquia, da mesma forma que um código HTML.
A grande questão é que parece um péssimo negócio trocar código HTML convencional por chamadas React.createElement().
E é mesmo um péssimo negócio, contornaremos isso em breve.
Por enquanto, alguns exercícios.
Site com tutoriais em português.
Bom vídeo (feito por terceiros) sobre o mesmo assunto.
Chaves de pesquisa: react basics
1. Tente escrever uma tabela fixa, com uma ou duas linhas, e veja o balai de gato que fica.