Conectando componentes em React ūüĒó

Uma das grandes vantagens de adotar a biblioteca React é a reutilização de código. E isso se dá através de seus componentes. React é extremamente poderoso nesse sentindo.

Voc√™ pode reutilizar componentes in√ļmeras vezes, evitando a repeti√ß√£o de c√≥digo desnecess√°ria e facilitando a manuten√ß√£o do mesmo. E isso se d√° com alguns simples passos.

No primeiro post criei uma aplica√ß√£o React bem simples. No √ļltimo post evolu√≠ a aplica√ß√£o inicial com o uso de JSX. Agora vou conectar diferentes componentes e formar uma aplica√ß√£o um pouco mais complexa. Para isso, vou criar um simples formul√°rio com um input para email, outro para senha e um bot√£o de ‚ÄúEnviar‚ÄĚ.

Vamos dar uma olhada como est√° o nosso arquivo index.html do post anterior:

<html>
  <head>
  </head>
  <body>
    <div id="react-container"></div>

    <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>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>

    <script src="Button.js"></script>

  </body>
</html>

At√© o momento tenho apenas um √ļnico componente: Button.js.

Para que o formul√°rio possa ser criado vou precisar de mais 3 componentes:

  • Input email
  • Input password
  • Formul√°rio (respons√°vel por englobar os outros componentes)

√Č claro que esta √© apenas uma maneira de fazer um formul√°rio. Eu poderia criar um √ļnico componente e colocar tudo l√° (o que acaba deixando dif√≠cil de manter).

No entanto, o nosso objetivo hoje é criar componentes que possam ser reutilizados.

Um componente Email pode ser utilizado em várias partes de uma aplicação, assim como um componente Button. Porém, se eu fizer tudo em um só componente veremos que ele não vai ser tão reutilizável assim, pois terá características exclusivas.

Vamos ver na pr√°tica como isso se d√°!?

Iniciando o servidor

Antes de iniciar com o código, preciso rodar o servidor local responsável por servir a página html e meus componentes React. Seguindo os passos do post de como configurar um servidor local, rapidamente consigo levantar um servidor Express e rodar minha aplicação.

Assim ficou a configuração do meu servidor:

// index.js
// importa o framework Express
const express = require("express");
// cria uma inst√Ęncia do express
const app = express();

// Carrega o arquivo index.html dentro da pasta dist
app.use("/", express.static(__dirname + "/dist"));

// Inicia o servidor Express na porta 5000
app.listen(5000, () => {
  console.log("servidor iniciado na porta 5000");
});

E assim est√° o meu package.json:

{
  "name": "form-react",
  "version": "1.0.0",
  "main": "index.js",
  "author": "Nelio",
  "license": "MIT",
  "dependencies": {
    "express": "^4.17.1"
  },
  "scripts": {
    "start": "node index.js"
  }
}

Agora basta rodar:

yarn start

E o meu servidor está pronto e esperando pela minha aplicação React.

Criando o campo email

Vou criar o novo componente EmailInput.js.

import React from "react";

class EmailInput extends React.Component {
  render() {
    return (
      <div>
        <label>Email: </label>
        <input type="email" />
      </div>
    );
  }
}

export default EmailInput;

Na maior parte do componente n√£o vemos nada de novo.

  • Defini a nossa classe EmailInput
  • Criei o m√©todo render respons√°vel por retornar os elementos que ser√£o renderizados na pagina.

Na √ļltima linha, escrevi algo que ainda n√£o tinha mostrado.

export default EmailInput;

O export diz ao compilador que este arquivo pode ser importado dentro de algum outro.

O default deixa claro qual classe (função ou variável) será, por padrão, chamada quando for importada. No caso acima a classe EmailInput.

Criando o campo password

Agora vou criar o segundo componente: PasswordInput.js.

import React from "react";

class PasswordInput extends React.Component {
  render() {
    return (
      <div>
        <label>Senha: </label>
        <input type="password" />
      </div>
    );
  }
}

export default PasswordInput;

Muito parecido com o componente email, n√£o √© mesmo!? A √ļnica diferen√ßa √© o atributo type do input HTML.

E por √ļltimo, vou criar o componente que ir√° importar EmailInput, PasswordInput e Button.

Criando o formul√°rio

E por fim, preciso de um componente que seja capaz de renderizar os outros dois componentes criados e, também, o componente Button criado anteriormente.

Vou cham√°-lo de Form.js:

import React from "react";
import EmailInput from "./EmailInput";
import PasswordInput from "./PasswordInput";
import Button from "./Button";

class Form extends React.Component {
  render() {
    return (
      <div>
        <h1>Meu primeiro formul√°rio</h1>
        <form name="first-form">
          <EmailInput />
          <br />
          <PasswordInput />
          <br />
          <Button />
        </form>
      </div>
    );
  }
}

export default Form;

Na segunda e terceira linha importei os componentes inputs criados ao longo do post. Este √© o motivo pelo qual adicionei export default e declarei exatamente qual classe gostaria de exportar. Desta maneira, os fiz ‚Äúexport√°veis‚ÄĚ.

Ap√≥s as importa√ß√Ķes, posso enfim, utiliz√°-los em outro componente - no caso, o Form.

Dentro do método render adicionei uma tag <form> para deixar claro para o navegador sobre o bloco que estou construindo. Então, adiciono EmailInput e PasswordInput da mesma maneira que escrevo qualquer outra tag HTML.

Carregando meu formul√°rio no HTML

Para que o meu arquivo Form.js seja carregado, preciso cham√°-lo dentro do arquivo index.js principal.

Este é o arquivo inicial e será o primeiro arquivo a ser carregado quando a aplicação estiver rodando. A partir deste arquivo inicial os outros componentes serão carregados.

Assim ficou o index.js:

import Form from "./Form";

const domContainer = document.querySelector("#react-container");
ReactDOM.render(React.createElement(Form), domContainer);

Vamos ao resultado:

Claramente n√£o era isso que eu esperava! ūüėĒ

Aparentemente o browser não consegue lidar com os imports e com a modularização da nossa aplicação.

Para resolver isso vamos precisar de outra ferramenta muito utilizada no mundo frontend: Webpack.

Instalando, configurando e utilizando o Webpack

Webpack é definido como um empacotador estático de módulos. Ele processa a minha aplicação e, internamente, cria um grafo de dependência com um ou mais pontos de entrada e então, combina cada módulo do projeto em um ou mais pacotes que serão servidos através do navegador.

Ou seja, ele facilita a modularização de uma aplicação, criando maneiras mais eficientes de acessar cada um dos muitos módulos criados.

Vamos à prática. Instale o webpack:

yarn add webpack webpack-cli --dev

Instale o Babel:

yarn add @babel/core @babel/preset-env @babel/preset-react --dev

Crie uma pasta chamada dist na raiz do seu projeto:

mdkir dist

Copie o index.html para a pasta dist

mv index.html dist/.

Assim est√° a estrutura do meu projeto:

react-app
|- package.json
|- index.js
|- /src
   |- Button.js
   |- index.js
   |- Form.js
   |- EmailInput.js
   |- PasswordInput.js
|- /dist
   |- index.html
|- /node_modules

Todo o código React da minha aplicação está dentro da pasta /src. O primeiro index.js, que está na raiz do projeto, é responsável pelo nosso servidor Express.

Um √ļltimo passo para utilizar webpack com React √© configurar como o processamento vai ser feito. Para isso vou criar um arquivo de configura√ß√£o na raiz do meu projeto:

touch webpack.config.js

Ao abrir o arquivo webpack.config.js vou adicionar as seguintes linhas:

module.exports = {
  entry: "./src/index.js",
  mode: "development",
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: { loader: "babel-loader" },
      },
    ],
  },
};

Com isso eu garanto que webpack vai sempre iniciar o processamento do meu código pelo arquivo src/index.js e vai utilizar o Babel - falo mais sobre ele aqui - para entender meu código React.

Por √ļltimo √© s√≥ utilizar o webpack para processar minha aplica√ß√£o e gerar o c√≥digo que vou utilizar em minha p√°gina.

npx webpack

Pronto! Meu arquivo JS foi gerado na pasta /dist com o nome main.js.

Hora de testar! ūü•Ā

Rodando o aplicativo

Será preciso uma pequena alteração no meu arquivo /dist/index.html lá do começo do post para que meu aplicativo rode corretamente. Vou substituir a tag script que está chamando o Button para que carregue o arquivo index.js gerado pelo webpack:

<html>
  <head>
  </head>
  <body>
    <div id="react-container"></div>

    <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>

    <script src="./main.js"></script>
  </body>
</html>

Pronto! Agora j√° posso testar no navegador.

Primeiro inicio o meu servidor local:

yarn start

Ent√£o, acesso a p√°gina localhost:5000

e‚Ķ ūüéČ:

Concluindo

Uma das principais vantagens de utilizar React e poder criar componentes que serão reutilizados em outras partes da aplicação. A famosa componentização que sempre vemos por aí. Cria-se uma vez e utiliza-se várias.

Tal vantagem facilita o desenvolvimento e o deixa mais r√°pido! ūüĎ®‚ÄćūüíĽūüí™

Próximos passos

Convenhamos que desenvolver software da maneira como fizemos neste post não é tão ágil assim. Por isso a comunidade JavaScript e React criaram ferramentas que vão nos ajudar a desenvolver apps React de modo muito mais rápido.

No próximo post vamos dar uma olhada no Create React App.

Até a próxima!

Se gostou desse artigo, se inscreva e receba semanalmente este e outros conte√ļdos diretamente no seu email. Sem spam! ūüėé

Compartilhe este artigo no Twitter.