React em 7 minutos
Tags: react, frontend
Published: 2020-09-27 00:53:53

# Disclaimer

Agradecimento especial para o Bootcamp da [RocketSeat](https://rocketseat.com.br/) que ensinou essa base toda de React já para muita gente.

Pressupoe-se que você tenha o gerenciador de pacotes [yarn](https://classic.yarnpkg.com/en/docs/install) instalado (similar ao Composer do PHP e pip do Python) e tenha um conhecimento básico em [Javascript ES6](https://www.w3schools.com/js/js_es6.asp).  Se não tiver, não se culpe, identifique o que não sabe e dá uma googlada 🤓.

Sugestões e feedbacks são mais do que muito bem-vindos.
## React? 

React foi parido em 2013 pelo Facebook para melhorar a maneira como até então estavam sendo criadas interfaces com Javascript.
Foi o primeiro framework reativo e, atualmente, é o [mais popular na web](https://insights.stackoverflow.com/survey/2019) e também a mesma forma de programar pode ser usada em interfaces mobile, usando React Native. A versão web do React é chamada de React DOM, porque manipula a árvore do DOM e renderiza os elementos com muito mais performance! Fora que é lindo de programar. Sabe por quê? 
Porque você altera os dados e a interface **reage a isso**. É sério! Vale a pena aprender, então trago aqui um gostinho de como ele funciona.

## Primeiros passos

O básico do básico para começar com React, principalmente para quem veio do Javascript com JQuery como eu vim, é entender 3 besteirinhas que são a base toda do framework:

- Componente
- Propriedade
- Estado

Com esses três já temos meio caminho andado, o resto é lucro.

## Como rodar isso no navegador?
Se você só quer ler de boas esse artigo e não pretende rodar projeto nenhum, pule direto para [Componentes](#componentes). Se quiser rodar, vai levar mais que 5 minutos, e recomendo ver essa intro de como configurar webpack e babel.


### Criando projeto

Aqui vamos criar a pasta e inicializar o projeto com o yarn. Você pode usar o npm, que é quase igual, mas você confere como usar um e outro [aqui](https://www.digitalocean.com/community/tutorials/nodejs-npm-yarn-cheatsheet).

👨‍💻 Terminal

```bash
mkdir react-7minutos
cd react-7minutos
yarn init -y
```

### Babel e Webpack

Esses são os dois caras que vão pegar o teu código React, feito com todas as features mais modernas do Javascript e rodar naquele navegador bosta que só tem 2 clientes teus que ainda usam mas você precisa dar suporte.

- **babel**: faz tradução de código javascript para código que o navegador entende
- **webpack**: usa os tradutores de cada tipo de arquivo (.js, .css, .png, .json) para importá-los e converte-los de uma forma diferente.
- **loaders**: image-loader, babel-loader, css-loader, são usados pelo webpack para carregar os arquivos nas aplicações

**Adicionando dependências e configurando os dois:**

👨‍💻 Terminal

```bash
yarn add babel-cli @babel/core @babel/preset-env @babel/preset-react webpack webpack-cli
```

👨‍💻 Terminal

```bash
yarn add babel-loader css-loader style-loader file-loader
```

**Criando arquivos de configuração**

📄 ./**babel.config.js**

*Esse arquivo vai dizer para o babel quais são as pré configurações que ele vai usar*

```jsx
module.exports = {
  presets : [
    "@babel/preset-env",
    "@babel/preset-react"
  ]
};
```

📄 ./**webpack.config.js**

*Esse arquivo adiciona as regras para o webpack saber quem vai fazer a conversão de cada tipo de arquivo*

```jsx
const path = require('path');

module.exports = {
  entry: path.resolve(__dirname, 'src', 'index.js'),
  output: {
    path: path.resolve(__dirname, 'public'),
    filename: 'bundle.js'
  },
  devServer: {
    contentBase: path.resolve(__dirname, 'public'),
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
        }
      },
      {
        test: /\.css$/,
        exclude: /node_modules/,
        use: [
          { loader: 'style-loader' },
          { loader: 'css-loader' },
        ]
      },
      {
        test: /.*\.(gif|png|jpe?g)$/i,
        use: {
          loader: 'file-loader',
        }
      }
    ]
  },
};
```

Rodar comando webpack em modo dev, aqui ele vai jogar uma c*ralhada de coisas para o arquivo ./public/bundle.js. Isso tudo é o que ele faz para carregar e traduzir cada arquivo. 

👨‍💻 Terminal

```bash
yarn webpack --mode development
```

Para que webpack fique monitorando arquivos e já faça automaticamente a tradução de cada um, pode ser usado o webpack-dev-server como dependência de dev.

👨‍💻 Terminal

```bash
yarn add webpack-dev-server -D
```

E agora sim, rodar o webpack dev server em modo dev.

Automaticamente um servidor na porta 8080 é ativado, e você pode ver cada alteração do código pelo navegador, com live reload, acessando localhost:8080.

👨‍💻 Terminal

```bash
yarn webpack-dev-server --mode development
```

A partir daqui tá clear para iniciar um novo projeto. 

By the way: create-react-app, gatsby e todos os outros geradores de boilerplate criam uma estrutura semelhante a essa para rodar react no navegador e ficar humanamente fácil de escrever código. Só coisa chata, mas tem que fazer né. Bora pro básico dos componentes.

---

## <a name="componentes">Componentes</a>

Aqui você vai ver uma sintaxe parecida com HTML, mas é escrita nos códigos Javascript do React. É chamada de JSX e praticamente toda tag HTML tem uma irmã-gemea em JSX.

Vou mostrando alguns arquivos e como eles estão sendo montados. 

📄 **./src/index.js**

*É o método render que faz a mágica, ele que vai montar a página como ela deve ser a partir do que for programado em JSX. Começamos aqui com um Hello World numa tag h1.*

```jsx
import React from 'react';
import { render } from 'react-dom';

render(
  <h1>Hello World</h1>, document.getElementById('app')
)
```

É uma boa prática sempre isolar os componentes, cada um em um arquivo.

📄 **./src/App.js**

*Criamos o componente chamado App, em forma de uma função que retorna um JSX, igual ao que foi feito antes.*

```jsx
import React from 'react';

function App() {
  return <h1>
    Hello World
  </h1>
}

export default App;
```

**📄 ./src/index.js**

*Aqui nós trocamos o componente direto, pelo novo componente personalizado App.*

```jsx
import React from 'react';
import { render } from 'react-dom';

import App from './App'

render(
  <App />, document.getElementById('app')
)
```

No vscode, ajuda ter essas configurações no arquivo settings.json, para ajudar o emmet a completar JSX em arquivos .js.

📝 vscode **📄 settings.json**

```json
"emmet.syntaxProfiles": {
  "javascript": "jsx"
},
"emmet.includeLanguages": {
  "javascript": "javascriptreact"
},
```

Para ficar mais organizado, podemos criar uma pasta exclusiva para componentes, como um componente de cabeçalho. Esse componente vai ajudar a reutilizar esse elemento em cada uma das páginas que forem criadas.

**📄 ./src/components/Header.js**

*Aqui ainda foi alterado o export default para antes da função, para ficar mais enxuto. Resultado é o mesmo.*

```jsx
import React from "react";

export default function Header() {
  return <h1>ReactJS</h1>;
}
```

Para adicionar mais de um componente dentro de outro componente, pode ser usado o fragment. É uma regra que o React tem de que cada componente pode retornar apenas um elemento, ou seja, uma tag que abre e fecha. O fragment vai funcionar como uma tag em branco.

**📄 ./src/components/App.js**

*Não faz muito sentido adicionar dois headers iguais em uma página, mas é um exemplo, não seja cricri.*

```jsx
import React from 'react';

import Header from './components/Header';
function App() {
  return <>
    <Header/>
    <Header/>
  </>
}

export default App;
```

✨ **Resultado**

![Fragmento não aparece no código final.](https://dev-to-uploads.s3.amazonaws.com/i/4u7bnpt56zh39573vwal.png)


## Propriedades (props)

Até agora tudo fácil. Só um header com um texto. Só que nem todo componente é essa belezinha né? 

Aqui que entram as propriedades. São formas de passar informações para cada componente, para ter uma maneira de não deixar eles tão estáticos, como esse que criamos com o texto ReactJS dentro dele. 

No header, faz sentido que a gente tenha um título nele, e cada componente possa chamar o título conforme for a página.

**📄 ./src/compoenents/App.js**

*Adicionamos um atributo na tag Header, na chamada do componente, chamado title (título). É bem intuitivo e fica parecendo uma tag html comum, e não JSX.*

```jsx
import React from 'react';

import Header from './components/Header';
function App() {
  return <>
    <Header title="Home"/>
    <Header title="Área do assinante"/>
  </>
}

export default App;
```

**📄 ./src/compoenents/Header.js**

*Dentro do componente, ele pode receber com parâmetro um elemento que chamamos de props, mas aqui poderia ser qualquer nome para a variável. Dentro dessa props, está o title que nós passamos na chamada do componente. Para usá-lo no componente, é só usar { chaves }.*

```jsx
import React from "react";

export default function Header(props) {
  return <h1>{props.title}</h1>;
}
```

*Fica legal e mais limpo só trazer a propriedade que vai ser usada, usando desestruturação.*

```jsx
import React from "react";

export default function Header({ title }) {
  return <h1>{title}</h1>;
}
```

✨ **Resultado**

![Alteramos o conteúdo de cada chamada do componente.](https://dev-to-uploads.s3.amazonaws.com/i/xgea7xbe6ib16d4f7js1.png)

Todo componente React tem uma propriedade chamanda children, que nada mais é do que o conteúdo dentro da tag.

**📄 ./src/compoenents/App.js**

Dentro do Header com `title` Home adicionamos uma lista `<ul>` com 3 `<li>`s. E o segundo Header continua como estava.

```jsx
import React from 'react';

import Header from './components/Header';
function App() {
  return <>
    <Header title="Home">
      <ul>
        <li>Solução</li>
        <li>Clientes</li>
        <li>Contato</li>
      </ul>
    </Header>
    <Header title="Área do assinante"/>
  </>
}

export default App;
```

**📄 ./src/compoenents/Header.js**

No componente, chamamos a propriedade children e usamos dentro do componente. Coloquei aqui também um header do html5 para circundar o conteúdo, para ficar no padrão.

```jsx
import React from "react";

export default function Header({ title, children }) {
  return (
    <header>
      <h1>{title}</h1>
      {children}
    </header>
  );
}
```

✨ **Resultado**

![Conteúdo filho da tag foi renderizado na primeira chamada do Header.](https://dev-to-uploads.s3.amazonaws.com/i/1rgmbm668jsspuo4w1fy.png)


## Estado e imutabilidade

Montamos o componente de Header, adicionamos uma propriedade de título para mudar o `<h1>` em cada um. Agora nós vamos criar mais um Header que lista alguns livros, que estão em um array. Isso tudo para entender o que é o estado e porque ele é tão mágico.

**📄 ./src/compoenents/App.js**

*Aqui importamos o useState da lib do React para trabalhar com o estado. Ele retorna um array com dois elementos, um é o próprio valor e o segundo é uma função para alterar esse valor.* 

*Aqui chamamos de books, e setBooks, porque faz mais sentido, mas pode ser usado qualquer nome.* 

*No componente Header de livros, nós pegamos esses livros (books) e fazemos um map para percorrer todo o array e trazer o `<li>` formatadinho com o nome do livro*

```jsx
import React, { useState } from "react";

import Header from './components/Header';
function App() {
  const [ books, setBooks ] = useState([
    'LOTR: a sociedade do anel',
    'LOTR: as duas torres',
    'LOTR: o retorno do rei',
  ])
  return <>
    <Header title="Home"/>
    <Header title="Livros">
      <ul>
        {books.map( book => (
            <li key={book}>{book}</li>
          )
        )}
      </ul>

    </Header>
    <Header title="Área do assinante"/>
  </>
}

export default App;
```

✨ **Resultado**

![Lista estática de livros. LOTR é Lord of The Rings, ou Senhor dos Anéis, para quem não pegou.](https://dev-to-uploads.s3.amazonaws.com/i/ryv3nr8i7gz7pdmlqki7.png)

🙉 Tá, mas uma lista estática eu já sabia adicionar, isso a gente já fez antes. 

Calma, agora que entra a mágica. Vamos adicionar um botão para adicionar um novo livro e ver ele atualizar na tela.

**📄 ./src/compoenents/App.js**

*Adicionamos um botão que tem um onClick chamando a função que criamos handleAddBook. Essa função usa o método useState para alterar o estado, e aí sim, o React já renderiza automagicamente na tela o novo livro adicionado.* 

*Cada livro tem um timestamp só para diferenciarmos cada novo livro adicionado.*

```jsx
import React, { useState } from "react";

import Header from './components/Header';
function App() {
  const [ books, setBooks ] = useState([
    'LOTR: a sociedade do anel',
    'LOTR: as duas torres',
    'LOTR: o retorno do rei',
  ]);

  function handleAddBook() {
    setBooks(
      [
        ...books,
        `Livro (${Date.now()})`
      ]
    );
    console.log(books);
  }

  return <>
    <Header title="Home"/>
    <Header title="Livros">
      <ul>
        {books.map( book => (
            <li key={book}>{book}</li>
          )
        )}
      </ul>
      <button type='button' onClick={handleAddBook}>Adicionar livro</button>
    </Header>
    <Header title="Área do assinante"/>
  </>
}

export default App;
```

✨ **Resultado**

![Alterando estado do componente e renderizando em tela o novo livro.](https://dev-to-uploads.s3.amazonaws.com/i/8j2g3cr01q0t8pea5fd9.gif)

Pronto, agora você já pode:

- 🗣️ Correr pros teus amigos e dizer que sabe React
- 🕴️ Adicionar nova competência no LinkedIn
- ✅ Fazer um projeto cliche de `To do List`, `Contador` ou `Calculadora`.
- 🙈 Publicar um curso de primeiros passos no Udemy
- 🤓 Começar a estudar React (a dica é o [starter da RocketSeat](https://app.rocketseat.com.br/node/curso-react-js), que além da didática ser ótima em vídeo também é 0800)