Skip to main content

šŸ“˜ ReactJS – Estrutura de Projeto, Componentes e Props

Introdução​

O ReactJS permite construir interfaces de usuÔrio a partir de componentes, ou seja, partes menores da interface que podem ser organizadas, combinadas e reutilizadas na construção de uma aplicação.

Antes de desenvolver aplicaƧƵes mais complexas, Ʃ importante compreender como um projeto ReactJS Ʃ estruturado e como seus diferentes arquivos se relacionam.

Neste capítulo, utilizaremos uma aplicação simples de Login para explorar a organização bÔsica de um projeto ReactJS e compreender como diferentes componentes podem ser utilizados em conjunto.

Ao longo do exemplo, serão apresentados componentes construídos de duas formas:

  • Componentes de Classe (Class Components);
  • Componentes Funcionais (Function Components).

TambƩm serƔ apresentado o conceito de Props (Properties), utilizado para transmitir informaƧƵes entre componentes.

O exemplo permitirÔ acompanhar o fluxo da aplicação desde o arquivo index.html até os componentes responsÔveis pela construção da interface.


šŸŽÆ Objetivos de Aprendizagem​

Ao concluir este capĆ­tulo, vocĆŖ deverĆ” ser capaz de:

  • compreender a estrutura bĆ”sica de um projeto ReactJS;
  • identificar o papel do arquivo index.html;
  • compreender a função do arquivo main.jsx;
  • identificar o componente raiz App;
  • compreender o conceito de componentização;
  • criar e utilizar componentes React;
  • diferenciar Componentes de Classe e Componentes Funcionais;
  • compreender a utilização de JSX;
  • utilizar fragmentos (<> </>) para agrupar elementos;
  • compreender o funcionamento de import e export;
  • compreender o conceito de Props;
  • transmitir informaƧƵes de um componente pai para um componente filho;
  • acessar Props utilizando this.props em componentes de classe;
  • utilizar desestruturação de Props em componentes funcionais;
  • compreender como diferentes componentes podem ser combinados para construir uma interface.

Estrutura do Projeto ReactJS​

Para compreender como os arquivos de uma aplicação ReactJS trabalham em conjunto, considere a estrutura utilizada neste capítulo.

Na raiz do projeto temos o arquivo:

index.html

O arquivo index.html carrega:

src/main.jsx

O arquivo main.jsx, por sua vez, utiliza o componente:

src/App.jsx

O componente App.jsx utiliza o componente:

components/props/Login.jsx

Finalmente, Login.jsx utiliza outros componentes responsÔveis pela construção da interface:

Label.jsx
Labelln.jsx
InputText.jsx
Button.jsx

Podemos representar esse fluxo da seguinte maneira:

index.html
│
ā–¼
main.jsx
│
ā–¼
App.jsx
│
ā–¼
Login.jsx
│
ā”œā”€ā”€ Label.jsx
│
ā”œā”€ā”€ Labelln.jsx
│
ā”œā”€ā”€ InputText.jsx
│
└── Button.jsx

Essa organização demonstra uma das principais características do ReactJS: a construção da interface a partir da composição de componentes.


Do index.html aos Componentes​

A aplicação começa pelo arquivo:

index.html

Nele existe um elemento que servirÔ como ponto de montagem da aplicação React:

<div id="root"></div>

O mesmo arquivo carrega o módulo:

<script type="module" src="/src/main.jsx"></script>

A partir desse ponto, o controle da construção da interface passa para os arquivos JavaScript/JSX da aplicação.

O arquivo main.jsx inicializa o React e solicita a renderização do componente:

<App />

O componente App, por sua vez, utiliza:

<Login />

JĆ” o componente Login combina componentes menores para construir a interface.

Portanto, existe uma sequência de composição:

HTML
│
ā–¼
React
│
ā–¼
App
│
ā–¼
Login
│
ā–¼
Componentes da Interface

Componentização​

Um dos conceitos centrais trabalhados neste capítulo é a componentização.

Em vez de construir toda a interface em um Ćŗnico arquivo, podemos dividi-la em partes menores.

No exemplo apresentado, a tela de Login utiliza quatro componentes:

ComponenteResponsabilidade
LabelExibir pequenos textos utilizados como rótulos.
LabellnExibir textos utilizados na composição da interface.
InputTextCriar campos de entrada de texto.
ButtonCriar um botão reutilizÔvel.

Esses componentes são posteriormente reunidos por:

Login.jsx

Assim:

                Login
│
ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│ │ │
Label InputText Button
│
Labelln

O diagrama representa conceitualmente a composição da interface. Os componentes Label, Labelln, InputText e Button são utilizados por Login para construir a tela.

Essa separação permite que os componentes sejam reutilizados em diferentes partes de uma aplicação.


Componentes de Classe e Componentes Funcionais​

O exemplo também apresenta duas formas de construção de componentes React.

Componentes de Classe​

Os componentes Label e Button são implementados utilizando classes.

A estrutura bÔsica segue o padrão:

class Componente extends React.Component {
render() {
return (
...
)
}
}

Nesse modelo, o componente herda de:

React.Component

e utiliza o mƩtodo:

render()

para definir o conteĆŗdo que serĆ” apresentado.

Componentes Funcionais​

Os componentes Labelln, InputText, Login e App são implementados utilizando funções.

A estrutura bƔsica Ʃ:

function Componente() {
return (
...
)
}

Nesse caso, uma função JavaScript retorna o JSX que representa a interface do componente.

Ao longo do capítulo, poderemos observar as diferenças entre essas duas formas de implementação.


Introdução Ć s Props​

Além da componentização, o exemplo introduz o conceito de Props.

Props são informações transmitidas de um componente para outro.

Considere:

<Label texto="UsuƔrio: " />

Nesse exemplo, o componente Label recebe uma propriedade chamada:

texto

com o valor:

UsuƔrio:

Outro exemplo aparece no componente InputText:

<InputText placeholder="user..." />

Nesse caso, Ć© transmitida a prop:

placeholder

TambƩm podemos transmitir informaƧƵes ao componente Button:

<Button valor="Logar" />

Portanto:

Componente Pai
│
│ Props
ā–¼
Componente Filho

As Props permitem utilizar um mesmo componente com diferentes informações, favorecendo sua reutilização.


šŸ“Œ Primeiros Conceitos-Chave​

ConceitoExplicação
ReactJSBiblioteca utilizada para construção de interfaces a partir de componentes.
ComponenteParte da interface que pode ser organizada e reutilizada.
ComponentizaçãoDivisão da interface em componentes menores.
ComposiçãoUtilização de componentes dentro de outros componentes.
Componente RaizComponente inicial utilizado para organizar a aplicação. No exemplo, App.
JSXSintaxe utilizada pelos componentes para representar a interface.
Class ComponentComponente implementado utilizando uma classe que herda de React.Component.
Function ComponentComponente implementado utilizando uma função.
PropsPropriedades utilizadas para transmitir informaƧƵes para componentes.
importPermite utilizar em um arquivo recursos definidos em outros módulos.
exportPermite disponibilizar um recurso para utilização em outros módulos.

šŸ’” Dicas do Professor​

Observe o fluxo da aplicação.

Antes de analisar cada componente isoladamente, procure compreender a sequĆŖncia index.html → main.jsx → App.jsx → Login.jsx. Ela ajuda a entender como a aplicação Ć© inicializada e como a interface Ć© construĆ­da.

Pense nos componentes como peƧas de uma interface.

Label, InputText e Button possuem responsabilidades especƭficas. O componente Login combina essas peƧas para formar uma interface maior.

Props tornam os componentes reutilizƔveis.

O mesmo componente Label pode apresentar diferentes textos simplesmente recebendo valores diferentes por meio da prop texto.

Observe as duas formas de criar componentes.

Neste capítulo são utilizados tanto componentes de classe quanto componentes funcionais. Compare suas estruturas durante os próximos exemplos.


Arquivo index.html​

O arquivo index.html representa o ponto inicial da aplicação no navegador.

Embora a interface seja construída pelos componentes React, ainda é necessÔrio um documento HTML responsÔvel por fornecer a estrutura inicial da pÔgina e indicar onde a aplicação serÔ montada.

No projeto utilizado neste capítulo, dois elementos são especialmente importantes:

<div id="root"></div>

e:

<script type="module" src="/src/main.jsx"></script>

O primeiro define o local no qual a aplicação React serÔ inserida.

O segundo carrega o arquivo main.jsx, responsÔvel por iniciar a aplicação.

O fluxo inicial pode ser representado por:

index.html
│
ā”œā”€ā”€ <div id="root">
│ ā–²
│ │ montagem da aplicação
│
└── main.jsx
│
ā–¼
React

šŸ’» Código Completo​

Arquivo: index.html

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>

šŸ“˜ ComentĆ”rios e ExplicaƧƵes Linha a Linha​

Linhas 01–02 — Estrutura inicial do documento​

<!doctype html>
<html lang="en">

A primeira linha:

<!doctype html>

indica que o documento utiliza HTML5.

Em seguida:

<html lang="en">

inicia o documento HTML e define o idioma da pƔgina por meio do atributo lang.

O elemento <html> funciona como elemento principal do documento e envolve as demais estruturas da pƔgina.


Linhas 03–08 — CabeƧalho da pĆ”gina​

<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React</title>
</head>

O elemento:

<head>

contém informações relacionadas à configuração e aos metadados da pÔgina.

A instrução:

<meta charset="UTF-8" />

define a codificação de caracteres utilizada pelo documento.

Em seguida:

<link rel="icon" type="image/svg+xml" href="/vite.svg" />

define o ƭcone utilizado pela pƔgina.

A configuração:

<meta name="viewport" content="width=device-width, initial-scale=1.0" />

orienta o navegador sobre a forma como a pƔgina deverƔ ser apresentada em diferentes tamanhos de tela.

Por fim:

<title>Vite + React</title>

define o tƭtulo apresentado pelo navegador para a pƔgina.


Linhas 09–12 — Corpo da pĆ”gina e inicialização da aplicação​

<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>

O elemento:

<body>

representa o corpo da pƔgina.

Dentro dele encontramos:

<div id="root"></div>

Esse elemento possui um papel fundamental na aplicação React.

Ele serĆ” utilizado como ponto de montagem da interface.

Inicialmente, o elemento estĆ” vazio:

<div id="root"></div>

Posteriormente, o React localizarĆ” esse elemento por meio de seu identificador:

root

e utilizarƔ esse espaƧo para inserir a interface construƭda pelos componentes.

A próxima instrução:

<script type="module" src="/src/main.jsx"></script>

carrega o arquivo:

/src/main.jsx

O atributo:

type="module"

indica que o arquivo JavaScript serÔ tratado como um módulo, permitindo trabalhar com recursos como import e export.

Assim, podemos representar a relação entre os dois elementos como:

index.html
│
ā”œā”€ā”€ #root
│ ā–²
│ │
│ React
│ │
│
└── main.jsx

O index.html disponibiliza o elemento root, enquanto main.jsx serÔ responsÔvel por iniciar o React e utilizar esse elemento para montar a aplicação.


Linha 13 — Finalização do documento​

</html>

A última linha encerra o elemento <html> iniciado no começo do documento.

Com isso, temos a estrutura completa do documento HTML que servirÔ como ponto inicial para a aplicação React.


O Papel do root​

O elemento:

<div id="root"></div>

estabelece a ligação entre o documento HTML e a aplicação React.

Podemos pensar no root como um ponto de entrada da interface React dentro da pƔgina HTML.

O fluxo pode ser representado da seguinte forma:

index.html
│
ā–¼
<div id="root">
ā–²
│
│ React monta a aplicação
│
main.jsx
│
ā–¼
<App />

No próximo arquivo estudado, main.jsx, veremos como o React localiza exatamente esse elemento.


O Papel de type="module"​

A instrução:

<script type="module" src="/src/main.jsx"></script>

não apenas carrega um arquivo JavaScript.

O atributo:

type="module"

indica que o arquivo serÔ tratado como um módulo.

Isso Ʃ importante porque os arquivos utilizados no projeto trabalham com instruƧƵes como:

import

e:

export

Por exemplo, main.jsx poderĆ” importar o componente App:

import App from './App.jsx'

A organização em módulos permite separar a aplicação em diferentes arquivos e estabelecer explicitamente as dependências entre eles.


šŸ“Œ Conceitos-Chave Envolvidos​

ConceitoExplicação
index.htmlDocumento HTML inicial utilizado pela aplicação.
HTML5Versão do HTML indicada por <!doctype html>.
<head>ContƩm metadados e configuraƧƵes do documento.
<body>Contém a estrutura utilizada na apresentação da pÔgina.
rootElemento utilizado como ponto de montagem da aplicação React.
idIdentificador que permite localizar um elemento no documento.
<script>Elemento utilizado para carregar o arquivo main.jsx.
type="module"Indica que o JavaScript serÔ tratado como módulo.
ES ModulesSistema de módulos que permite utilizar import e export.
main.jsxArquivo responsÔvel por iniciar a aplicação React no exemplo.

šŸ’” Dicas do Professor​

O React não elimina a necessidade do index.html.

O navegador ainda precisa carregar inicialmente um documento HTML. A aplicação React é posteriormente montada dentro desse documento.

Observe que o root comeƧa vazio.

Não escrevemos manualmente a interface da aplicação dentro de <div id="root"></div>. Ela serÔ construída pelos componentes React.

O identificador root serĆ” utilizado novamente.

Ao estudar main.jsx, observe como o mesmo nome definido em id="root" serÔ utilizado para localizar o ponto de montagem da aplicação.

type="module" estÔ relacionado à modularização do projeto.

Ele permite que o arquivo carregado trabalhe com a organização modular utilizada pelos arquivos da aplicação.


Arquivo main.jsx​

Depois que o navegador carrega o index.html, o arquivo main.jsx é responsÔvel por inicializar a aplicação React.

Na parte anterior, vimos que o index.html possui:

<div id="root"></div>

e carrega:

<script type="module" src="/src/main.jsx"></script>

Agora podemos compreender como main.jsx utiliza esse elemento root para montar a aplicação.

O fluxo Ć©:

index.html
│
ā–¼
main.jsx
│
ā”œā”€ā”€ localiza #root
│
ā”œā”€ā”€ cria a raiz React
│
└── renderiza <App />
│
ā–¼
App.jsx

šŸ’» Código Completo​

Arquivo: /src/main.jsx

import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App.jsx'

createRoot(document.getElementById('root'))
.render(
<StrictMode>
<App />
</StrictMode>,
)

šŸ“˜ ComentĆ”rios e ExplicaƧƵes Linha a Linha​

Linhas 01–04 — ImportaƧƵes iniciais​

import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App.jsx'

As quatro primeiras linhas definem os recursos necessÔrios para inicializar a aplicação.

Na primeira linha:

import { StrictMode } from 'react'

Ć© importado o StrictMode da biblioteca React.

O StrictMode é utilizado durante o desenvolvimento para auxiliar na identificação de possíveis problemas e incentivar a utilização de boas prÔticas.

Na segunda linha:

import { createRoot } from 'react-dom/client'

é importada a função createRoot.

Essa função permite criar a raiz React que serÔ associada a um elemento existente no documento HTML.

Na terceira linha:

import './index.css'

é importado o arquivo que contém os estilos globais da aplicação.

Diferentemente das demais importações, não estamos importando uma função ou componente para uma variÔvel. O arquivo CSS é carregado para que seus estilos sejam aplicados à aplicação.

Finalmente:

import App from './App.jsx'

importa o componente App.

Esse componente serĆ” utilizado como componente raiz da interface.


Linha 05 — Separação entre importaƧƵes e inicialização​

A linha 05 estĆ” em branco.

Ela não possui efeito na execução do programa, mas ajuda a separar visualmente:

ImportaƧƵes
│
ā–¼
Inicialização da aplicação

Essa organização contribui para tornar o código mais legível.


Linha 06 — Criação da raiz React​

createRoot(document.getElementById('root'))

Essa linha estabelece a ligação entre o React e o elemento definido anteriormente no index.html.

Primeiro Ć© executado:

document.getElementById('root')

Esse comando procura no documento HTML um elemento cujo id seja:

root

No index.html, encontramos exatamente:

<div id="root"></div>

Portanto:

index.html                         main.jsx

<div id="root"></div> ◄──── document.getElementById('root')

O elemento encontrado é então fornecido para:

createRoot(...)

Assim, o React cria uma raiz associada ao elemento HTML.

Podemos representar esse processo como:

document
│
ā–¼
getElementById('root')
│
ā–¼
<div id="root">
│
ā–¼
createRoot(...)
│
ā–¼
Raiz React

Linhas 07–11 — Renderização da aplicação​

.render(
<StrictMode>
<App />
</StrictMode>,
)

Depois que a raiz React Ʃ criada, o mƩtodo:

.render(...)

define o conteĆŗdo que serĆ” renderizado.

Dentro dele encontramos:

<StrictMode>
<App />
</StrictMode>

O componente:

<App />

representa a interface principal da aplicação.

Ele estĆ” envolvido por:

<StrictMode>

que ativa verificaƧƵes adicionais durante o desenvolvimento.

O resultado conceitual Ć©:

<div id="root">
│
ā–¼
StrictMode
│
ā–¼
App

A partir desse momento, o React passa a controlar a interface apresentada dentro do elemento root.


Relação entre index.html e main.jsx​

Agora podemos observar a ligação completa entre os dois primeiros arquivos estudados.

No index.html:

<div id="root"></div>

Ć© criado o ponto de montagem.

TambƩm no index.html:

<script type="module" src="/src/main.jsx"></script>

Ʃ carregado o arquivo responsƔvel por inicializar o React.

Em main.jsx:

document.getElementById('root')

localiza esse elemento.

Em seguida:

createRoot(...)

cria a raiz React.

Finalmente:

.render(
<StrictMode>
<App />
</StrictMode>,
)

renderiza o componente App.

O fluxo completo Ć©:

index.html
│
ā”œā”€ā”€ cria <div id="root">
│
└── carrega main.jsx
│
ā–¼
getElementById('root')
│
ā–¼
createRoot()
│
ā–¼
render()
│
ā–¼
<StrictMode>
│
ā–¼
<App />

StrictMode​

O StrictMode Ć© um recurso do React utilizado para auxiliar o desenvolvimento.

Ele Ć© importado por:

import { StrictMode } from 'react'

e utilizado envolvendo o componente principal:

<StrictMode>
<App />
</StrictMode>

No contexto do exemplo, sua função é ajudar a identificar possíveis problemas durante o desenvolvimento e reforçar boas prÔticas.

O StrictMode não representa um elemento visual da interface.

Ou seja:

StrictMode
│
ā”œā”€ā”€ auxilia o desenvolvimento
ā”œā”€ā”€ realiza verificaƧƵes adicionais
└── envolve <App />

createRoot()​

A função:

createRoot()

é responsÔvel por criar a raiz da aplicação React.

No exemplo:

createRoot(document.getElementById('root'))

o argumento fornecido é o elemento HTML no qual a aplicação deverÔ ser montada.

Podemos interpretar a instrução em duas etapas:

1. Encontrar o elemento HTML

document.getElementById('root')

│
ā–¼

2. Criar a raiz React nesse elemento

createRoot(...)

Depois de criada a raiz, utilizamos:

.render(...)

para definir o que deverĆ” ser apresentado.


O Componente Raiz App​

A instrução:

import App from './App.jsx'

importa o componente App.

Posteriormente:

<App />

utiliza esse componente dentro da interface.

O App funciona como componente raiz da aplicação apresentada neste exemplo.

Isso significa que ele serÔ responsÔvel por iniciar a composição dos demais componentes da interface.

A hierarquia estudada atƩ este momento Ʃ:

index.html
│
ā–¼
main.jsx
│
ā–¼
<App />

Na próxima parte, veremos que App utiliza outro componente:

<Login />

ampliando a hierarquia:

index.html
│
ā–¼
main.jsx
│
ā–¼
App.jsx
│
ā–¼
Login.jsx

CSS Global​

A instrução:

import './index.css'

carrega o arquivo de estilos globais utilizado pela aplicação.

Nesse modelo de projeto, um arquivo CSS pode ser importado diretamente pelo JavaScript/JSX.

Assim:

main.jsx
│
ā”œā”€ā”€ index.css
│
└── App.jsx

O index.css pode definir estilos bÔsicos que serão utilizados pela aplicação.

Conforme o projeto cresce, outros arquivos de estilo podem ser organizados juntamente com seus respectivos componentes.


šŸ“Œ Conceitos-Chave Envolvidos​

ConceitoExplicação
main.jsxArquivo responsÔvel pela inicialização da aplicação React no exemplo.
StrictModeRecurso utilizado para auxiliar na identificação de problemas durante o desenvolvimento.
createRoot()Cria uma raiz React associada a um elemento do documento HTML.
document.getElementById()Localiza um elemento HTML utilizando seu identificador.
rootIdentificador do elemento utilizado como ponto de montagem da aplicação.
.render()Define o conteĆŗdo que serĆ” renderizado pela raiz React.
AppComponente raiz utilizado pela aplicação.
<App />Utilização do componente App em JSX.
index.cssArquivo utilizado para os estilos globais da aplicação.
importPermite utilizar recursos definidos em outros módulos.
JSXSintaxe utilizada para representar componentes e elementos da interface.

šŸ’” Dicas do Professor​

Relacione root nos dois arquivos.

O id="root" definido em index.html deve corresponder ao identificador procurado por document.getElementById('root') em main.jsx.

NĆ£o confunda a raiz HTML com o componente raiz.

<div id="root"> Ć© o elemento HTML utilizado como ponto de montagem. App, por sua vez, Ć© o componente React principal renderizado nesse ponto.

Observe a sequĆŖncia createRoot() → .render().

Primeiro o React cria uma raiz associada ao elemento HTML. Depois define qual componente deverĆ” ser renderizado nessa raiz.

<App /> é um componente, não uma tag HTML.

Em JSX, componentes React são utilizados de maneira semelhante às tags HTML. A inicial maiúscula ajuda a diferenciÔ-los dos elementos HTML tradicionais.

O StrictMode Ć© utilizado durante o desenvolvimento.

Ele auxilia na identificação de situações que merecem atenção, mas não representa nenhum elemento visual da pÔgina.


Componente App.jsx​

Depois que o arquivo main.jsx inicializa o React, o componente App passa a representar o componente raiz da interface.

Na parte anterior, vimos a seguinte instrução:

<App />

Ela solicita ao React que renderize o componente definido no arquivo:

/src/App.jsx

Neste exemplo, App possui uma responsabilidade simples: utilizar o componente Login.

A hierarquia passa a ser:

index.html
│
ā–¼
main.jsx
│
ā–¼
App.jsx
│
ā–¼
Login.jsx

Essa relação introduz um conceito importante no desenvolvimento com React: componentes podem utilizar outros componentes para construir interfaces maiores.


šŸ’» Código Completo​

Arquivo: /src/App.jsx

import Login from "./components/props/Login.jsx"

function App() {
return (
<>
<Login />
</>
)
}

export default App

šŸ“˜ ComentĆ”rios e ExplicaƧƵes Linha a Linha​

Linha 01 — Importação do componente Login​

import Login from "./components/props/Login.jsx"

A primeira linha importa o componente Login.

O caminho:

./components/props/Login.jsx

indica a localização do arquivo em relação ao arquivo App.jsx.

A instrução:

import

permite utilizar dentro de App um componente definido em outro arquivo.

Podemos representar essa dependĆŖncia como:

App.jsx
│
│ import
ā–¼
Login.jsx

Essa separação é uma característica importante da componentização.

Em vez de implementar toda a interface diretamente em App.jsx, podemos dividir a aplicação em componentes menores e utilizÔ-los conforme necessÔrio.


Linha 02 — Separação entre importação e componente​

A linha 02 estĆ” em branco.

Ela separa visualmente:

Importação
│
ā–¼
Definição do componente

Embora não altere o funcionamento da aplicação, essa organização melhora a legibilidade do código.


Linhas 03–09 — Definição do componente App​

function App() {
return (
<>
<Login />
</>
)
}

A instrução:

function App() {

declara uma função JavaScript chamada App.

No React, uma função que retorna uma interface utilizando JSX pode ser utilizada como um Function Component.

Portanto:

Função JavaScript
│
│ retorna JSX
ā–¼
Function Component

O nome:

App

começa com letra maiúscula.

Essa convenção é importante para diferenciar componentes React de elementos HTML tradicionais.

Por exemplo:

<div>

representa um elemento HTML.

Enquanto:

<App />

representa um componente React.


Linhas 04–08 — Retorno da interface com JSX​

return (
<>
<Login />
</>
)

A instrução:

return

define o conteĆŗdo que o componente deverĆ” apresentar.

O conteĆŗdo retornado utiliza JSX.

JSX permite escrever estruturas semelhantes ao HTML dentro do código JavaScript.

Neste exemplo, o conteĆŗdo principal retornado por App Ć©:

<Login />

Portanto, quando o React renderiza:

<App />

o componente App solicita a renderização de:

<Login />

A relação pode ser representada por:

<App />
│
ā–¼
<Login />

Linhas 05 e 07 — Utilização de Fragmento​

<>
<Login />
</>

Os sĆ­mbolos:

<>

e:

</>

representam um Fragmento (Fragment) do React.

Um fragmento permite agrupar elementos JSX sem adicionar um novo elemento HTML ao DOM.

Por exemplo, poderĆ­amos utilizar:

<div>
<Login />
</div>

Entretanto, nesse caso seria criado um elemento <div> adicional na estrutura HTML.

Com:

<>
<Login />
</>

os elementos podem ser agrupados sem criar essa <div> adicional.

Conceitualmente:

Fragment
│
└── Login

O fragmento organiza o retorno JSX, mas não representa uma <div> adicional na interface.


Linha 06 — Renderização do componente Login​

<Login />

Essa instrução utiliza o componente Login importado na primeira linha.

Observe a relação:

import Login from "./components/props/Login.jsx"

e:

<Login />

Primeiro, o componente Ć© importado.

Depois, ele pode ser utilizado dentro do JSX.

Podemos representar esse processo como:

Login.jsx
│
│ export
ā–¼
App.jsx
│
│ import
ā–¼
<Login />

O componente Login serÔ responsÔvel por organizar outros componentes menores utilizados na construção da tela.


Linha 10 — Separação antes da exportação​

A linha 10 estĆ” em branco.

Ela separa a definição do componente de sua exportação.

A organização do arquivo fica, portanto:

Importação
│
ā–¼
Componente
│
ā–¼
Exportação

Linha 11 — Exportação do componente​

export default App

A Ćŗltima linha exporta o componente App.

A instrução:

export default

indica que App representa a exportação padrão desse módulo.

Isso permite que outro arquivo utilize:

import App from './App.jsx'

Foi exatamente o que ocorreu no arquivo main.jsx.

Assim:

App.jsx
│
│ export default App
ā–¼
main.jsx
│
│ import App
ā–¼
<App />

O mecanismo de import e export permite organizar a aplicação em diferentes arquivos sem perder a relação entre eles.


Function Component​

O componente App é implementado como uma função:

function App() {
return (
...
)
}

Essa forma de construção é denominada Function Component.

Um componente funcional pode receber informações e retornar JSX para definir sua representação na interface.

Neste primeiro exemplo, App possui uma estrutura bastante simples:

App
│
└── retorna
│
ā–¼
Login

Posteriormente, outros componentes poderão apresentar estruturas mais elaboradas.


JSX​

No componente App, encontramos:

<Login />

Essa sintaxe faz parte do JSX.

O JSX permite representar elementos e componentes de maneira declarativa.

Por exemplo, elementos HTML podem aparecer como:

<div>
<p>OlĆ”!</p>
</div>

Enquanto componentes React podem aparecer como:

<Login />

Uma diferença visual importante é a utilização da letra inicial maiúscula nos componentes:

<div>       → elemento HTML

<Login /> → componente React

Essa distinção serÔ observada ao longo de todo o projeto.


Fragmentos​

Quando um componente precisa agrupar elementos, podemos utilizar um fragmento:

<>
...
</>

No exemplo:

<>
<Login />
</>

o fragmento envolve o componente Login.

Uma das principais caracterĆ­sticas desse recurso Ć© permitir o agrupamento sem criar um elemento adicional no DOM.

Compare:

<div>
<Login />
</div>

com:

<>
<Login />
</>

No primeiro caso, existe uma <div> adicional.

No segundo, o fragmento realiza apenas o agrupamento necessƔrio ao JSX.


Composição de Componentes​

AtƩ este momento, jƔ temos dois componentes relacionados:

App
│
ā–¼
Login

App não precisa conhecer todos os detalhes internos de Login.

Ele apenas utiliza:

<Login />

Esse princípio permite construir interfaces maiores por meio da combinação de componentes menores.

A estrutura da aplicação começa a assumir a seguinte organização:

                    index.html
│
ā–¼
main.jsx
│
ā–¼
App
│
ā–¼
Login
│
ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│ │ │
Label InputText Button
│
Labelln

Nos próximos componentes veremos como Login é construído a partir dessas partes menores.


Relação entre main.jsx e App.jsx​

Podemos agora conectar os conceitos das duas partes.

Em main.jsx:

import App from './App.jsx'

carrega o componente.

Depois:

<App />

solicita sua renderização.

Em App.jsx:

export default App

disponibiliza o componente para outros módulos.

Assim:

App.jsx
│
│ export default
ā–¼
main.jsx
│
│ import
ā–¼
<App />
│
ā–¼
<Login />

Essa relação entre exportação, importação e composição serÔ repetida diversas vezes durante a construção da aplicação.


šŸ“Œ Conceitos-Chave Envolvidos​

ConceitoExplicação
AppComponente raiz da interface utilizado no exemplo.
Function ComponentComponente React implementado utilizando uma função.
JSXSintaxe utilizada para representar a interface dentro do código JavaScript.
<App />Utilização do componente App.
<Login />Utilização do componente Login dentro de App.
FragmentoPermite agrupar elementos JSX sem adicionar um elemento extra ao DOM.
<> </>Sintaxe simplificada utilizada para criar um fragmento.
ComponentizaçãoOrganização da interface em componentes menores.
ComposiçãoConstrução de um componente utilizando outros componentes.
importPermite utilizar um recurso exportado por outro módulo.
export defaultDefine a exportação padrão de um módulo.
Componente RaizComponente principal a partir do qual a interface Ć© organizada.

šŸ’” Dicas do Professor​

Observe a letra inicial dos componentes.

App e Login começam com letra maiúscula. Essa característica permite diferenciÔ-los visualmente de elementos HTML como div, input e button.

Importar não significa renderizar.

A instrução import Login ... apenas torna o componente disponível no arquivo. A utilização <Login /> é que o inclui na interface retornada por App.

App não precisa implementar toda a interface.

Sua função pode ser organizar outros componentes. Essa divisão de responsabilidades é uma das bases da componentização.

Observe o caminho inverso entre import e export.

App.jsx utiliza export default App, enquanto main.jsx utiliza import App. Da mesma forma, Login.jsx exportarĆ” Login para que App.jsx possa importĆ”-lo.

Fragmentos evitam elementos desnecessƔrios.

<> </> permite organizar o JSX sem adicionar uma <div> apenas para realizar o agrupamento.


Componentes Label.jsx e Labelln.jsx​

AtƩ este momento, vimos que o componente App utiliza:

<Login />

O componente Login, por sua vez, serĆ” construĆ­do a partir de componentes menores.

Entre esses componentes estão:

Label.jsx
Labelln.jsx
InputText.jsx
Button.jsx

Nesta parte, estudaremos Label e Labelln.

Os dois componentes possuem uma característica em comum: recebem um texto por meio de Props e utilizam esse valor na construção da interface.

Entretanto, eles foram implementados utilizando abordagens diferentes:

Label.jsx
│
└── Class Component
│
└── this.props.texto


Labelln.jsx
│
└── Function Component
│
└── { texto }

Essa diferença permite comparar duas formas de construção de componentes e duas maneiras de acessar Props.


Componente Label.jsx

O componente Label Ʃ responsƔvel por receber um texto e apresentƔ-lo na interface.

No formulƔrio de Login, ele serƔ utilizado, por exemplo, para apresentar:

UsuƔrio:

e:

Senha:

O componente Ć© implementado utilizando uma classe que herda de React.Component.


šŸ’» Código Completo​

Arquivo: /src/components/props/Label.jsx

import React from 'react';

export default class Label extends React.Component{
render(){
return(
<>
{this.props.texto}
</>
);
}
}

šŸ“˜ ComentĆ”rios e ExplicaƧƵes Linha a Linha​

Linha 01 — Importação do React​

import React from 'react';

A primeira linha importa o objeto React.

Essa importação serÔ utilizada na declaração:

React.Component

que servirĆ” como classe-base para Label.


Linha 02 — Separação entre importação e componente​

A linha 02 estĆ” em branco.

Ela separa visualmente a importação da declaração do componente.

A organização fica:

Importação
│
ā–¼
Declaração da classe

Linha 03 — Declaração do componente de classe​

export default class Label extends React.Component{

Essa linha reĆŗne trĆŖs elementos importantes.

Primeiro:

class Label

declara uma classe chamada Label.

Em seguida:

extends React.Component

indica que Label herda de React.Component.

Por fim:

export default

define Label como a exportação padrão do módulo.

Podemos representar essa estrutura como:

React.Component
ā–²
│ extends
│
Label
│
│ export default
ā–¼
outros componentes

Por herdar de React.Component, Label pode ser utilizado como um componente React baseado em classe.


Linhas 04–10 — MĆ©todo render()​

render(){
return(
<>
{this.props.texto}
</>
);
}

Componentes baseados em classe utilizam o mƩtodo:

render()

para definir o conteĆŗdo que serĆ” apresentado na interface.

Dentro de render(), encontramos:

return(...)

responsƔvel por retornar o JSX do componente.

Neste caso, o JSX apresenta o valor recebido pela prop:

texto

Linhas 06–08 — Fragmento e utilização da Prop​

<>
{this.props.texto}
</>

O componente utiliza novamente um Fragmento:

<>
</>

Dentro dele encontramos:

{this.props.texto}

Em JSX, as chaves:

{ }

permitem inserir uma expressão JavaScript dentro da estrutura da interface.

Como Label Ć© um componente de classe, as propriedades recebidas podem ser acessadas por:

this.props

Portanto:

this.props.texto

significa:

this
│
ā–¼
props
│
ā–¼
texto

Ou seja, estamos acessando a prop chamada texto recebida pelo componente.


Linha 11 — Finalização da classe​

}

A última linha encerra a declaração da classe Label.

Com isso, temos um componente completo que:

recebe uma Prop
│
ā–¼
this.props.texto
│
ā–¼
render()
│
ā–¼
interface

Utilizando o Componente Label​

Posteriormente, o componente poderĆ” ser utilizado da seguinte forma:

<Label texto="UsuƔrio: " />

Nesse caso:

Prop        Valor

texto → "UsuĆ”rio: "

Dentro de Label, o valor poderĆ” ser acessado utilizando:

{this.props.texto}

Assim:

<Login />
│
│ texto="UsuĆ”rio: "
ā–¼
<Label />
│
ā–¼
this.props.texto
│
ā–¼
"UsuƔrio: "

O mesmo componente pode ser reutilizado com outro valor:

<Label texto="Senha: " />

Agora:

texto  →  "Senha: "

A estrutura do componente não precisa ser modificada.

Apenas o valor da Prop Ć© diferente.


šŸ“Œ Conceitos-Chave Envolvidos em Label​

ConceitoExplicação
Class ComponentComponente implementado utilizando uma classe.
React.ComponentClasse-base utilizada pelo componente Label.
extendsEstabelece a heranƧa de React.Component.
render()MƩtodo que define o JSX apresentado pelo componente de classe.
PropsInformaƧƵes recebidas pelo componente.
this.propsPermite acessar as Props em um componente de classe.
this.props.textoAcessa especificamente a Prop texto.
{ }Permite inserir uma expressão JavaScript dentro do JSX.
export defaultDefine Label como exportação padrão do módulo.

šŸ’” Dicas do Professor​

Observe que Label não define o texto que apresenta.

O texto Ć© recebido de outro componente por meio de Props. Isso permite reutilizar Label com diferentes valores.

Em um Class Component, observe o uso de this.props.

Neste exemplo, this.props.texto acessa a propriedade texto recebida pelo componente.

O método render() possui uma função importante.

Em um componente de classe, ele define o conteĆŗdo JSX que serĆ” apresentado.


Componente Labelln.jsx

O componente Labelln possui uma finalidade semelhante Ć  de Label: receber um texto e apresentĆ”-lo na interface.

Entretanto, sua implementação utiliza uma função, permitindo observar outra forma de construção de componentes React.

No formulƔrio utilizado neste capƭtulo, ele serƔ utilizado para apresentar o texto:

Login

Sua estrutura também introduz a desestruturação de Props.


šŸ’» Código Completo​

Arquivo: /src/components/props/Labelln.jsx

import React from 'react';

export default function Labelln({ texto }) {
return (
<>
{texto} <br />
</>
);
}

šŸ“˜ ComentĆ”rios e ExplicaƧƵes Linha a Linha​

Linha 01 — Importação do React​

import React from 'react';

O arquivo inicia importando React.

No exemplo do material, essa importação é mantida no componente funcional.


Linha 02 — Separação entre importação e componente​

A linha 02 estĆ” em branco.

Ela separa a importação da declaração do componente.


Linha 03 — Declaração do Function Component​

export default function Labelln({ texto }) {

Essa linha declara uma função chamada:

Labelln

Como a função retorna JSX e serÔ utilizada como componente React, temos um Function Component.

A declaração também utiliza:

export default

permitindo que Labelln seja importado por outros módulos.

Observe o parâmetro:

{ texto }

Ele representa a desestruturação das Props recebidas pelo componente.


Desestruturação de Props​

Um componente recebe suas Props como um objeto.

Conceitualmente, podemos imaginar:

props = {
texto: "Login"
}

Uma forma de acessar esse valor seria:

props.texto

Entretanto, Labelln utiliza desestruturação diretamente no parâmetro:

function Labelln({ texto })

Assim, a propriedade:

texto

é extraída do objeto recebido e pode ser utilizada diretamente dentro da função.

Podemos representar:

Props
│
ā–¼
{
texto: "Login"
}
│
│ desestruturação
ā–¼
texto
│
ā–¼
"Login"

Linhas 04–08 — Retorno JSX​

return (
<>
{texto} <br />
</>
);

O componente retorna JSX utilizando:

return

Dentro do fragmento encontramos:

{texto}

Como a Prop jÔ foi desestruturada no parâmetro da função, não é necessÔrio escrever:

props.texto

Podemos utilizar diretamente:

texto

Linha 06 — Exibição da Prop e quebra de linha​

{texto} <br />

As chaves:

{texto}

inserem o valor da variƔvel texto no JSX.

Em seguida:

<br />

adiciona uma quebra de linha.

Assim, se o componente for utilizado como:

<Labelln texto="Login" />

a Prop recebida serĆ”:

texto  →  "Login"

e o componente apresentarĆ” esse valor seguido de uma quebra de linha.


Linha 09 — Finalização do componente​

}

A última linha encerra a função Labelln.

O fluxo do componente pode ser representado como:

<Labelln texto="Login" />
│
ā–¼
Props
│
ā–¼
{ texto }
│
ā–¼
texto
│
ā–¼
JSX + <br />

Utilizando o Componente Labelln​

O componente poderĆ” ser utilizado por Login da seguinte forma:

<Labelln texto="Login" />

O valor:

Login

Ć© enviado por meio da Prop:

texto

O componente recebe:

{ texto }

e utiliza:

{texto}

para apresentar esse conteĆŗdo.


Comparando Label e Labelln

Agora podemos comparar os dois componentes.

Label​

Ɖ implementado como classe:

export default class Label extends React.Component

e acessa a Prop utilizando:

this.props.texto

Labelln​

Ɖ implementado como função:

export default function Labelln({ texto })

e utiliza desestruturação para acessar diretamente:

texto

Podemos resumir:

CaracterĆ­sticaLabelLabelln
TipoClass ComponentFunction Component
Estruturaclassfunction
BaseReact.ComponentFunção JavaScript
Método render()SimNão
Prop utilizadatextotexto
Acesso Ć  Propthis.props.textotexto
DesestruturaçãoNãoSim
Retorna JSXSimSim
export defaultSimSim

Apesar das diferenças de implementação, os dois componentes recebem informações por meio de Props.


Props: Componente Pai → Componente Filho​

Os dois exemplos permitem compreender uma caracterĆ­stica importante das Props.

Os valores são fornecidos quando o componente é utilizado.

Por exemplo:

<Label texto="UsuƔrio: " />

ou:

<Labelln texto="Login" />

Podemos representar essa relação como:

Componente Pai
│
│ texto="..."
ā–¼
Componente Filho
│
ā–¼
Prop

No exemplo completo, Login serƔ o componente responsƔvel por fornecer esses valores:

Login
│
ā”œā”€ā”€ texto="Login"
│ │
│ ā–¼
│ Labelln
│
ā”œā”€ā”€ texto="UsuĆ”rio: "
│ │
│ ā–¼
│ Label
│
└── texto="Senha: "
│
ā–¼
Label

Essa comunicação permite que componentes menores sejam reutilizados com conteúdos diferentes.


Props e Reutilização​

Considere:

<Label texto="UsuƔrio: " />

e:

<Label texto="Senha: " />

O componente utilizado Ć© exatamente o mesmo:

Label

O que muda Ć© o valor da Prop:

             Label
/ \
/ \
"UsuƔrio: " "Senha: "

Esse comportamento demonstra uma das vantagens da componentização: podemos criar uma estrutura uma única vez e configurÔ-la por meio das informações recebidas.


šŸ“Œ Conceitos-Chave Envolvidos​

ConceitoExplicação
PropsPropriedades utilizadas para transmitir informaƧƵes para um componente.
Componente PaiComponente que utiliza outro componente e fornece suas Props.
Componente FilhoComponente que recebe as Props.
Class ComponentComponente implementado por meio de uma classe.
Function ComponentComponente implementado por meio de uma função.
React.ComponentClasse-base utilizada na implementação de Label.
render()MƩtodo utilizado pelo Class Component para retornar JSX.
this.propsForma utilizada no exemplo para acessar Props no componente de classe.
DesestruturaçãoRecurso JavaScript utilizado para extrair propriedades de um objeto.
{ texto }Desestrutura a propriedade texto recebida pelo Function Component.
{this.props.texto}Insere no JSX a Prop texto em Label.
{texto}Insere no JSX a Prop desestruturada em Labelln.
<br />Elemento utilizado no exemplo para inserir uma quebra de linha.
ReutilizaçãoPossibilidade de utilizar o mesmo componente com diferentes valores de Props.

šŸ’” Dicas do Professor​

Compare os dois componentes, não apenas seus resultados.

Label e Labelln recebem uma Prop chamada texto, mas fazem isso utilizando estruturas diferentes. Essa comparação ajuda a compreender Class Components e Function Components.

Props podem ser entendidas como informaƧƵes fornecidas ao componente.

Quando escrevemos <Label texto="UsuƔrio: " />, estamos fornecendo um valor para a propriedade texto.

Observe a desestruturação em Labelln.

{ texto } no parâmetro permite utilizar diretamente texto dentro da função, evitando a escrita props.texto.

Não confunda as chaves utilizadas na desestruturação com as chaves do JSX.

Em function Labelln({ texto }), as chaves fazem parte da desestruturação do objeto de Props. Em {texto} dentro do JSX, as chaves permitem inserir uma expressão JavaScript na interface.

A reutilização ficarÔ mais evidente em Login.jsx.

O mesmo Label serÔ utilizado para apresentar valores diferentes, demonstrando na prÔtica a relação entre Props e componentização.


Componente InputText.jsx

O componente InputText Ʃ responsƔvel por criar um campo de entrada de texto reutilizƔvel.

No formulƔrio de Login, ele serƔ utilizado para representar os campos destinados ao usuƔrio e Ơ senha.

Em vez de criar diretamente diferentes elementos <input> no componente Login, serÔ utilizado um componente que recebe por meio de Props a informação necessÔria para configurar o campo.

No exemplo, a Prop utilizada serĆ”:

placeholder

Assim, o mesmo componente poderÔ ser utilizado com diferentes textos de orientação.


šŸ’» Código Completo​

Arquivo: /src/components/props/InputText.jsx

import React from 'react';

export default function InputText({ placeholder }) {
return (
<input type="text" placeholder={placeholder} />
);
}

šŸ“˜ ComentĆ”rios e ExplicaƧƵes Linha a Linha​

Linha 01 — Importação do React​

import React from 'react';

O arquivo inicia importando React.

No exemplo apresentado, essa importação é mantida no componente funcional.


Linha 02 — Separação entre importação e componente​

A linha 02 estĆ” em branco.

Ela separa visualmente a importação da declaração do componente.


Linha 03 — Declaração do Function Component​

export default function InputText({ placeholder }) {

Essa linha declara um Function Component chamado:

InputText

Assim como ocorreu em Labelln, as Props são recebidas utilizando desestruturação.

A expressão:

{ placeholder }

extrai a propriedade placeholder do objeto de Props recebido pelo componente.

Conceitualmente:

Props
│
ā–¼
{
placeholder: "user..."
}
│
│ desestruturação
ā–¼
placeholder
│
ā–¼
"user..."

A declaração também utiliza:

export default

permitindo que InputText seja importado e utilizado por outros componentes.


Linhas 04–06 — Retorno do campo de entrada​

return (
<input type="text" placeholder={placeholder} />
);

O componente retorna um elemento HTML:

<input>

O atributo:

type="text"

indica que se trata de um campo de entrada de texto.

JĆ”:

placeholder={placeholder}

define dinamicamente o texto de orientação apresentado dentro do campo.

Observe que existem dois usos da palavra placeholder:

placeholder={placeholder}

O primeiro:

placeholder=

corresponde ao atributo do elemento <input>.

O segundo:

{placeholder}

corresponde ao valor recebido pelo componente por meio das Props.

Assim:

Prop do componente
│
ā–¼
placeholder
│
ā–¼
atributo do <input>
│
ā–¼
texto apresentado no campo

Linha 07 — Finalização do componente​

}

A última linha encerra a função InputText.

O componente completo pode ser compreendido pelo seguinte fluxo:

<InputText placeholder="user..." />
│
ā–¼
Props
│
ā–¼
{ placeholder }
│
ā–¼
placeholder
│
ā–¼
<input type="text">

Utilizando o Componente InputText​

No formulƔrio de Login, o componente poderƔ ser utilizado como:

<InputText placeholder="user..." />

Nesse caso:

placeholder  →  "user..."

O componente utiliza esse valor em:

<input type="text" placeholder={placeholder} />

O mesmo componente tambƩm poderƔ ser reutilizado:

<InputText placeholder="password..." />

Agora:

placeholder  →  "password..."

A implementação de InputText permanece a mesma.

Somente a Prop fornecida pelo componente pai Ć© modificada.


Props em Atributos JSX​

Nos componentes anteriores, utilizamos uma Prop como conteĆŗdo:

{texto}

Em InputText, a Prop Ć© utilizada de outra maneira:

placeholder={placeholder}

Isso demonstra que expressƵes JavaScript podem ser utilizadas tambƩm para definir valores de atributos em JSX.

Compare:

<Labelln texto="Login" />

Dentro de Labelln:

{texto}

e:

<InputText placeholder="user..." />

Dentro de InputText:

<input type="text" placeholder={placeholder} />

Portanto, uma Prop pode ser utilizada tanto no conteúdo apresentado pelo componente quanto na configuração dos elementos que ele retorna.


Input NĆ£o Controlado​

No exemplo apresentado, InputText apenas cria o campo:

<input type="text" placeholder={placeholder} />

Não existe um estado associado ao valor digitado e também não existe, neste momento, um evento para acompanhar suas alterações.

Por isso, o exemplo apresenta um input não controlado.

Neste capítulo, o objetivo estÔ concentrado na componentização e na utilização de Props.

A captura e o gerenciamento dos valores digitados poderão ser tratados posteriormente com outros recursos do React.


šŸ“Œ Conceitos-Chave Envolvidos em InputText​

ConceitoExplicação
Function ComponentComponente implementado utilizando uma função.
PropsInformaƧƵes recebidas pelo componente.
placeholderProp utilizada para configurar o texto de orientação do campo.
DesestruturaçãoPermite extrair placeholder diretamente das Props.
<input>Elemento HTML utilizado para entrada de dados.
type="text"Define o campo como entrada de texto.
placeholder={placeholder}Utiliza uma expressão JavaScript para definir dinamicamente o atributo.
Input não controladoCampo cujo valor não estÔ sendo gerenciado por um estado React no exemplo.
ReutilizaçãoPermite utilizar o mesmo InputText com diferentes valores de placeholder.

šŸ’” Dicas do Professor​

Observe onde a Prop estĆ” sendo utilizada.

Em Labelln, texto aparece como conteĆŗdo do componente. Em InputText, placeholder Ć© utilizado para definir dinamicamente um atributo do elemento <input>.

NĆ£o confunda os dois placeholder.

Em placeholder={placeholder}, o primeiro identifica o atributo do elemento e o segundo representa a variÔvel obtida por meio da desestruturação das Props.

O componente ainda não captura o valor digitado.

Neste momento, InputText tem como objetivo demonstrar componentização e Props. O gerenciamento do conteúdo do campo exige outros recursos que serão estudados posteriormente.


Componente Button.jsx

O próximo componente representa um botão reutilizÔvel.

No formulƔrio de Login, ele serƔ utilizado para apresentar:

Logar

Assim como Label, o componente Button Ć© implementado utilizando uma classe que herda de:

React.Component

O texto apresentado pelo botão serÔ recebido por meio da Prop:

valor

šŸ’» Código Completo​

Arquivo: /src/components/props/Button.jsx

import React from 'react';

export default class Button extends React.Component {
render() {
return (
<button>
{this.props.valor}
</button>
);
}
}

šŸ“˜ ComentĆ”rios e ExplicaƧƵes Linha a Linha​

Linha 01 — Importação do React​

import React from 'react';

O arquivo importa React, que serÔ utilizado na declaração:

React.Component

Linha 02 — Separação entre importação e componente​

A linha 02 estĆ” em branco.

Ela separa a importação da declaração da classe.


Linha 03 — Declaração do componente Button​

export default class Button extends React.Component {

Essa linha declara uma classe chamada:

Button

A expressão:

extends React.Component

estabelece que Button herda de React.Component.

Portanto, sua estrutura Ć© semelhante Ć  utilizada anteriormente em Label:

React.Component
ā–²
│
ā”œā”€ā”€ Label
│
└── Button

A declaração também utiliza:

export default

para disponibilizar Button como exportação padrão do módulo.


Linhas 04–10 — MĆ©todo render()​

render() {
return (
<button>
{this.props.valor}
</button>
);
}

Como Button Ć© um componente de classe, utiliza:

render()

para definir o JSX que serĆ” apresentado.

Dentro do return, encontramos um elemento HTML:

<button>
</button>

Esse elemento representa o botão que serÔ apresentado na interface.


Linhas 06–08 — Elemento <button> e Prop valor​

<button>
{this.props.valor}
</button>

O conteúdo do botão não estÔ definido diretamente no componente.

Em vez de escrever:

<button>
Logar
</button>

o componente utiliza:

{this.props.valor}

Assim como vimos em Label, this.props permite acessar as Props recebidas por um componente de classe.

A propriedade utilizada Ć©:

valor

Portanto:

this
│
ā–¼
props
│
ā–¼
valor

O valor recebido serĆ” utilizado como conteĆŗdo do elemento <button>.


Linha 11 — Finalização da classe​

}

A Ćŗltima linha encerra a classe Button.

Seu funcionamento pode ser representado por:

<Button valor="Logar" />
│
ā–¼
Props
│
ā–¼
this.props.valor
│
ā–¼
"Logar"
│
ā–¼
<button>Logar</button>

Utilizando o Componente Button​

No componente Login, o botão serÔ utilizado como:

<Button valor="Logar" />

Nesse caso:

valor  →  "Logar"

Dentro do componente, esse valor serĆ” acessado por:

{this.props.valor}

O resultado serÔ um botão cujo texto é definido pela Prop recebida.

O componente tambƩm poderia ser reutilizado com outros valores:

<Button valor="Cadastrar" />

ou:

<Button valor="Cancelar" />

A estrutura de Button não precisaria ser modificada.


Comparando InputText e Button

Os dois componentes representam elementos de uma interface, mas utilizam formas diferentes de implementação.

InputText Ć© um Function Component:

export default function InputText({ placeholder })

e recebe sua Prop utilizando desestruturação:

{ placeholder }

JĆ” Button Ć© um Class Component:

export default class Button extends React.Component

e acessa sua Prop utilizando:

this.props.valor

Podemos comparar:

CaracterĆ­sticaInputTextButton
TipoFunction ComponentClass Component
Estruturafunctionclass
Prop utilizadaplaceholdervalor
Acesso Ć  Propplaceholderthis.props.valor
DesestruturaçãoSimNão
Método render()NãoSim
Elemento retornado<input><button>
export defaultSimSim
ReutilizƔvelSimSim

Evolução da Composição da Interface​

Agora jĆ” conhecemos os quatro componentes utilizados por Login:

Label.jsx
Labelln.jsx
InputText.jsx
Button.jsx

Cada um possui uma responsabilidade especĆ­fica:

ComponenteTipoPropResponsabilidade
LabelClass ComponenttextoApresentar um texto utilizado como rótulo.
LabellnFunction ComponenttextoApresentar um texto seguido de uma quebra de linha.
InputTextFunction ComponentplaceholderApresentar um campo de entrada de texto.
ButtonClass ComponentvalorApresentar um botão com texto configurÔvel.

Podemos visualizar a futura composição:

Login
│
ā”œā”€ā”€ Labelln
│ └── texto
│
ā”œā”€ā”€ Label
│ └── texto
│
ā”œā”€ā”€ InputText
│ └── placeholder
│
ā”œā”€ā”€ Label
│ └── texto
│
ā”œā”€ā”€ InputText
│ └── placeholder
│
└── Button
└── valor

O componente Login não precisarÔ implementar novamente o funcionamento de cada elemento.

Sua responsabilidade serĆ” combinar e configurar esses componentes por meio das Props.


šŸ“Œ Conceitos-Chave Envolvidos​

ConceitoExplicação
Function ComponentForma utilizada para implementar InputText.
Class ComponentForma utilizada para implementar Button.
PropsInformaƧƵes fornecidas aos componentes.
Desestruturação de PropsForma utilizada por InputText para acessar placeholder.
this.propsForma utilizada por Button para acessar suas Props.
placeholderProp utilizada para configurar o campo de entrada.
valorProp utilizada para definir o texto do botão.
<input>Elemento HTML utilizado para entrada de dados.
<button>Elemento HTML utilizado para representar um botão.
JSXPermite combinar elementos e expressƵes JavaScript na interface.
Input não controladoCampo cujo valor não é gerenciado por estado no exemplo.
ReutilizaçãoPossibilidade de utilizar os componentes com diferentes valores de Props.
ComponentizaçãoDivisão da interface em componentes com responsabilidades específicas.

šŸ’” Dicas do Professor​

Observe como as Props tornam os componentes configurƔveis.

InputText não precisa saber antecipadamente qual texto deverÔ aparecer como placeholder, assim como Button não precisa saber qual texto deverÔ apresentar.

Compare novamente Function Component e Class Component.

InputText recebe placeholder por desestruturação, enquanto Button utiliza this.props.valor. Essa diferença reforça as duas formas de implementação apresentadas neste capítulo.

Componentização não significa apenas dividir arquivos.

Cada componente deve possuir uma responsabilidade clara. Neste exemplo, InputText representa um campo de entrada e Button representa um botão.

Ainda não existe comportamento associado ao botão.

O componente apresenta o elemento <button> e seu texto, mas o material ainda não adiciona uma ação de clique. Neste momento, o foco permanece na estrutura dos componentes e na utilização de Props.

Observe como estamos preparando o Login.

Agora jÔ possuímos todas as peças necessÔrias. Na próxima parte, Login.jsx reunirÔ Label, Labelln, InputText e Button, demonstrando de forma completa a composição e a passagem de Props.


Componente Login.jsx

Depois de criarmos os componentes:

Label.jsx
Labelln.jsx
InputText.jsx
Button.jsx

podemos utilizĆ”-los em conjunto para construir uma interface maior.

Essa responsabilidade serĆ” atribuĆ­da ao componente:

Login.jsx

Diferentemente dos componentes anteriores, Login não representa apenas um elemento específico da interface.

Sua principal responsabilidade Ć© organizar e combinar outros componentes.

A composição pode ser representada por:

Login
│
ā”œā”€ā”€ Labelln
│
ā”œā”€ā”€ Label
│
ā”œā”€ā”€ InputText
│
ā”œā”€ā”€ Label
│
ā”œā”€ā”€ InputText
│
└── Button

AlƩm de utilizar esses componentes, Login fornece os valores das Props necessƔrias para configurƔ-los.


šŸ’» Código Completo​

Arquivo: /src/components/props/Login.jsx

import Label from "./Label.jsx"
import Labelln from "./Labelln.jsx"
import Button from "./Button.jsx"
import InputText from "./InputText.jsx"

function Login() {
return (
<>
<Labelln texto="Login"/>
<Label texto="UsuƔrio: "/>
<InputText placeholder="user..."/> <br />
<Label texto="Senha: "/>
<InputText placeholder="password..."/> <br />
<Button valor="Logar" />
</>
)
}

export default Login

šŸ“˜ ComentĆ”rios e ExplicaƧƵes Linha a Linha​

Linhas 01–04 — Importação dos componentes​

import Label from "./Label.jsx"
import Labelln from "./Labelln.jsx"
import Button from "./Button.jsx"
import InputText from "./InputText.jsx"

As primeiras linhas importam os quatro componentes utilizados para construir a interface de Login.

Cada componente estÔ definido em seu próprio arquivo:

Login.jsx
│
ā”œā”€ā”€ Label.jsx
ā”œā”€ā”€ Labelln.jsx
ā”œā”€ā”€ Button.jsx
└── InputText.jsx

Como todos esses componentes foram definidos utilizando:

export default

podemos importĆ”-los diretamente pelo nome utilizado no arquivo Login.jsx.

Por exemplo:

import Label from "./Label.jsx"

torna o componente Label disponível para utilização dentro do JSX de Login.

Essa organização demonstra a modularização da aplicação.

Cada componente possui sua própria implementação, enquanto Login é responsÔvel por reuni-los.


Linha 05 — Separação entre importaƧƵes e componente​

A linha 05 estĆ” em branco.

Ela separa visualmente:

ImportaƧƵes
│
ā–¼
Definição do componente

Essa separação não interfere na execução, mas contribui para a organização e a legibilidade do código.


Linhas 06–17 — Definição do componente Login​

function Login() {
return (
<>
<Labelln texto="Login"/>
<Label texto="UsuƔrio: "/>
<InputText placeholder="user..."/> <br />
<Label texto="Senha: "/>
<InputText placeholder="password..."/> <br />
<Button valor="Logar" />
</>
)
}

A instrução:

function Login() {

declara um Function Component chamado Login.

Assim como App, esse componente utiliza uma função JavaScript que retorna JSX.

Entretanto, existe uma diferenƧa importante.

App utilizava apenas:

<Login />

JĆ” Login combina diversos componentes menores.

Podemos representar:

App
│
ā–¼
Login
│
ā”œā”€ā”€ Labelln
ā”œā”€ā”€ Label
ā”œā”€ā”€ InputText
ā”œā”€ā”€ Label
ā”œā”€ā”€ InputText
└── Button

Isso demonstra como componentes simples podem ser combinados para construir componentes maiores.


Linhas 07–16 — Retorno JSX​

return (
<>
<Labelln texto="Login"/>
<Label texto="UsuƔrio: "/>
<InputText placeholder="user..."/> <br />
<Label texto="Senha: "/>
<InputText placeholder="password..."/> <br />
<Button valor="Logar" />
</>
)

O return define a interface que serĆ” apresentada pelo componente.

Nesse caso, o JSX não é composto diretamente apenas por elementos HTML.

Grande parte da interface Ć© construĆ­da utilizando os componentes criados anteriormente:

Labelln
Label
InputText
Button

Isso demonstra a composição de componentes.


Linhas 08 e 15 — Fragmento​

<>

e:

</>

delimitam um Fragmento.

O fragmento permite que Login retorne vƔrios elementos sem precisar adicionar uma <div> apenas para agrupƔ-los.

Dentro dele estão todos os componentes utilizados para construir a interface.

Conceitualmente:

Fragment
│
ā”œā”€ā”€ Labelln
ā”œā”€ā”€ Label
ā”œā”€ā”€ InputText
ā”œā”€ā”€ Label
ā”œā”€ā”€ InputText
└── Button

Linha 09 — TĆ­tulo da interface​

<Labelln texto="Login"/>

O componente Labelln recebe a Prop:

texto

com o valor:

Login

Na parte anterior, vimos que Labelln recebe essa propriedade utilizando desestruturação:

function Labelln({ texto })

e apresenta o valor utilizando:

{texto}

Portanto, o fluxo Ć©:

Login.jsx
│
│ texto="Login"
ā–¼
Labelln
│
ā–¼
{ texto }
│
ā–¼
"Login"

Linhas 10–11 — Campo destinado ao usuĆ”rio​

<Label texto="UsuƔrio: "/>
<InputText placeholder="user..."/> <br />

Essas duas instruƧƵes constroem a parte da interface destinada ao usuƔrio.

Primeiro:

<Label texto="UsuƔrio: "/>

utiliza o componente Label e fornece:

texto  →  "UsuĆ”rio: "

Como Label Ć© um Class Component, o valor serĆ” acessado internamente por:

this.props.texto

Em seguida:

<InputText placeholder="user..."/>

utiliza o componente InputText e fornece:

placeholder  →  "user..."

Como InputText é um Function Component com desestruturação, o valor é recebido por:

{ placeholder }

e utilizado no elemento:

<input type="text" placeholder={placeholder} />

O elemento:

<br />

adiciona uma quebra de linha após o campo.


Linhas 12–13 — Campo destinado Ć  senha​

<Label texto="Senha: "/>
<InputText placeholder="password..."/> <br />

A mesma estrutura utilizada anteriormente Ć© reutilizada.

O componente:

<Label texto="Senha: "/>

recebe agora outro valor para a Prop texto:

texto  →  "Senha: "

JĆ”:

<InputText placeholder="password..."/>

recebe:

placeholder  →  "password..."

Observe que não foi necessÔrio criar novos componentes para representar esses campos.

Os mesmos componentes:

Label
InputText

foram reutilizados com Props diferentes.

Podemos visualizar:

                Label
/ \
/ \
"UsuƔrio: " "Senha: "


InputText
/ \
/ \
"user..." "password..."

Essa reutilização é uma das principais vantagens da componentização.


Linha 14 — BotĆ£o da interface​

<Button valor="Logar" />

A Ćŗltima parte da interface utiliza o componente:

Button

A Prop:

valor

recebe:

Logar

Como Button Ć© um Class Component, o valor serĆ” acessado internamente utilizando:

{this.props.valor}

O fluxo Ć©:

Login
│
│ valor="Logar"
ā–¼
Button
│
ā–¼
this.props.valor
│
ā–¼
"Logar"

Linha 18 — Separação antes da exportação​

A linha 18 estĆ” em branco.

Ela separa a declaração do componente de sua exportação.


Linha 19 — Exportação do componente​

export default Login

A última linha exporta Login como conteúdo padrão do módulo.

Isso permite que App.jsx utilize:

import Login from "./components/props/Login.jsx"

e posteriormente:

<Login />

Portanto:

Login.jsx
│
│ export default Login
ā–¼
App.jsx
│
│ import Login
ā–¼
<Login />

Passagem de Props​

O componente Login permite visualizar claramente como ocorre a passagem de Props.

Considere:

<Label texto="UsuƔrio: "/>

Nesse caso, Login Ć© o componente pai, enquanto Label Ć© o componente filho.

A informação é transmitida da seguinte forma:

Login
│
│ texto="UsuĆ”rio: "
ā–¼
Label
│
ā–¼
this.props.texto

Outro exemplo:

<InputText placeholder="user..."/>

Nesse caso:

Login
│
│ placeholder="user..."
ā–¼
InputText
│
ā–¼
{ placeholder }

Portanto, no exemplo apresentado, as Props estabelecem um fluxo de informaƧƵes do componente pai para seus componentes filhos.


Props Diferentes para Componentes Diferentes​

Cada componente pode definir as propriedades necessƔrias para sua responsabilidade.

No exemplo:

<Labelln texto="Login"/>

utiliza:

texto

Assim como:

<Label texto="UsuƔrio: "/>

JĆ”:

<InputText placeholder="user..."/>

utiliza:

placeholder

e:

<Button valor="Logar" />

utiliza:

valor

Podemos resumir:

ComponentePropValor utilizado no exemplo
Labellntexto"Login"
Labeltexto"UsuƔrio: "
InputTextplaceholder"user..."
Labeltexto"Senha: "
InputTextplaceholder"password..."
Buttonvalor"Logar"

Isso demonstra que as Props funcionam como uma forma de configurar cada utilização de um componente.


Reutilização de Componentes​

Um dos aspectos mais importantes do exemplo estÔ na reutilização.

Label Ć© utilizado duas vezes:

<Label texto="UsuƔrio: "/>

e:

<Label texto="Senha: "/>

Da mesma forma, InputText Ć© utilizado duas vezes:

<InputText placeholder="user..."/>

e:

<InputText placeholder="password..."/>

Não foi necessÔrio criar:

LabelUsuario
LabelSenha
InputUsuario
InputSenha

Os mesmos componentes foram configurados com diferentes Props.

Assim:

Componente
│
ā”œā”€ā”€ estrutura reutilizĆ”vel
│
└── Props
│
ā–¼
configuração específica

Separação de Responsabilidades​

A estrutura criada também demonstra a separação de responsabilidades.

Cada componente possui uma função específica:

Labelln
│
└── apresenta texto e quebra de linha

Label
│
└── apresenta um texto

InputText
│
└── apresenta um campo de entrada

Button
│
└── apresenta um botĆ£o

Login
│
└── organiza os componentes

O componente Login não precisa conhecer os detalhes de implementação de cada componente.

Por exemplo, ele não precisa saber que Label utiliza:

this.props.texto

ou que InputText utiliza:

{ placeholder }

Ele apenas fornece as Props esperadas.

Essa divisão torna a estrutura da aplicação mais organizada.


Hierarquia Completa da Aplicação​

Agora jĆ” podemos visualizar toda a estrutura estudada neste capĆ­tulo:

index.html
│
│ carrega
ā–¼
main.jsx
│
│ renderiza
ā–¼
App
│
│ utiliza
ā–¼
Login
│
ā”œā”€ā”€ Labelln
│ └── texto="Login"
│
ā”œā”€ā”€ Label
│ └── texto="UsuĆ”rio: "
│
ā”œā”€ā”€ InputText
│ └── placeholder="user..."
│
ā”œā”€ā”€ Label
│ └── texto="Senha: "
│
ā”œā”€ā”€ InputText
│ └── placeholder="password..."
│
└── Button
└── valor="Logar"

Essa hierarquia demonstra como uma aplicação React pode ser construída progressivamente.

ComeƧamos com:

index.html

que disponibiliza o ponto de montagem.

Depois:

main.jsx

inicializa o React.

Em seguida:

App.jsx

organiza a aplicação.

Por fim:

Login.jsx

combina componentes menores para construir a interface.


Composição Ɨ Reutilização Ɨ Props​

Os trĆŖs conceitos podem ser observados simultaneamente no componente Login.

Composição​

Login Ć© construĆ­do utilizando outros componentes:

Login
│
ā”œā”€ā”€ Label
ā”œā”€ā”€ Labelln
ā”œā”€ā”€ InputText
└── Button

Reutilização​

Label e InputText aparecem mais de uma vez:

<Label texto="UsuƔrio: "/>
<Label texto="Senha: "/>

e:

<InputText placeholder="user..."/>
<InputText placeholder="password..."/>

Props​

Cada utilização pode receber valores diferentes:

Componente reutilizƔvel
│
│ Props
ā–¼
Configuração específica

Esses conceitos trabalham em conjunto e constituem elementos importantes para a organização de interfaces em React.


FormulĆ”rio Apresentado no Exemplo​

Embora o componente represente visualmente uma tela de Login, neste momento o exemplo estĆ” concentrado na estrutura da interface e no uso de Props.

Os campos:

<InputText placeholder="user..."/>

e:

<InputText placeholder="password..."/>

ainda não possuem gerenciamento dos valores digitados.

Da mesma forma:

<Button valor="Logar" />

ainda não possui uma ação associada ao clique.

Portanto, neste estƔgio:

Interface de Login
│
ā”œā”€ā”€ componentes
ā”œā”€ā”€ Props
ā”œā”€ā”€ composição
└── apresentação

O comportamento do formulƔrio poderƔ ser acrescentado posteriormente com outros recursos do React.


šŸ“Œ Conceitos-Chave Envolvidos​

ConceitoExplicação
LoginFunction Component responsƔvel por organizar a interface apresentada no exemplo.
Componente PaiComponente que utiliza e fornece Props para outros componentes.
Componente FilhoComponente utilizado por outro componente e que pode receber Props.
PropsInformaƧƵes transmitidas para configurar componentes.
ComposiçãoConstrução de uma interface por meio da combinação de componentes.
ReutilizaçãoUtilização do mesmo componente mais de uma vez com diferentes Props.
ModularizaçãoOrganização dos componentes em arquivos separados.
importTorna os componentes exportados disponĆ­veis em Login.jsx.
export defaultDisponibiliza Login para utilização em outro módulo.
FragmentoAgrupa os elementos retornados por Login sem adicionar uma <div> extra.
textoProp utilizada pelos componentes Label e Labelln.
placeholderProp utilizada por InputText.
valorProp utilizada por Button.
Separação de ResponsabilidadesDistribuição das diferentes partes da interface entre componentes específicos.

šŸ’” Dicas do Professor​

Observe que Login é responsÔvel principalmente pela composição.

Ele não implementa novamente um campo de entrada, um botão ou um rótulo. Em vez disso, utiliza componentes que jÔ possuem essas responsabilidades.

O componente pai fornece as Props.

Em <Label texto="UsuƔrio: " />, Login fornece a Prop texto, enquanto Label Ʃ responsƔvel por utilizƔ-la.

Reutilizar um componente não significa apresentar sempre a mesma informação.

As Props permitem utilizar a mesma estrutura com valores diferentes. Por isso, Label pode representar tanto "UsuƔrio: " quanto "Senha: ".

A interface ainda não possui a lógica de autenticação.

Os campos não estão sendo gerenciados por estado e o botão ainda não possui uma ação associada. O objetivo deste exemplo é compreender estrutura, componentização e Props.

Observe a aplicação como uma hierarquia.

A sequĆŖncia index.html → main.jsx → App → Login → componentes ajuda a compreender como partes menores sĆ£o organizadas para formar a interface completa.



šŸ“Œ Conceitos-Chave Envolvidos​

Ao longo deste capítulo, acompanhamos o fluxo completo de uma aplicação ReactJS simples, desde o documento HTML inicial até a composição da interface de Login.

Os principais conceitos estudados podem ser sintetizados da seguinte forma:

ConceitoExplicação
index.htmlDocumento HTML inicial que disponibiliza o ponto de montagem da aplicação React.
rootElemento HTML no qual a interface React Ć© montada.
main.jsxArquivo responsÔvel por inicializar a aplicação React.
createRoot()Cria uma raiz React associada ao elemento definido no documento HTML.
.render()Define o conteĆŗdo que serĆ” renderizado pela raiz React.
StrictModeRecurso utilizado durante o desenvolvimento para auxiliar na identificação de possíveis problemas.
AppComponente raiz da interface apresentado no exemplo.
ComponenteParte da interface que possui uma responsabilidade especĆ­fica e pode ser combinada com outros componentes.
ComponentizaçãoDivisão da interface em componentes menores.
ComposiçãoConstrução de componentes maiores utilizando componentes menores.
ReutilizaçãoUtilização do mesmo componente em diferentes situações, alterando sua configuração por meio de Props.
JSXSintaxe utilizada para representar elementos e componentes dentro do código JavaScript.
FragmentoPermite agrupar elementos JSX sem adicionar um elemento HTML adicional ao DOM.
<> </>Sintaxe simplificada utilizada para representar um fragmento.
Function ComponentComponente React implementado utilizando uma função.
Class ComponentComponente React implementado utilizando uma classe que herda de React.Component.
React.ComponentClasse-base utilizada pelos componentes de classe apresentados no capĆ­tulo.
render()MƩtodo utilizado pelos Class Components para retornar JSX.
PropsInformações fornecidas a um componente para configurar sua utilização.
this.propsForma utilizada nos componentes de classe do exemplo para acessar Props.
Desestruturação de PropsRecurso utilizado nos componentes funcionais para acessar diretamente propriedades recebidas.
importPermite utilizar recursos disponibilizados por outros módulos.
export defaultDefine a exportação padrão de um módulo.
ModularizaçãoOrganização da aplicação em diferentes arquivos e componentes.

Integração dos Conceitos​

A estrutura construĆ­da ao longo do capĆ­tulo pode ser representada pela seguinte hierarquia:

index.html
│
│ carrega
ā–¼
main.jsx
│
│ inicializa o React
ā–¼
App.jsx
│
│ utiliza
ā–¼
Login.jsx
│
ā”œā”€ā”€ Labelln.jsx
│ └── texto
│
ā”œā”€ā”€ Label.jsx
│ └── texto
│
ā”œā”€ā”€ InputText.jsx
│ └── placeholder
│
ā”œā”€ā”€ Label.jsx
│ └── texto
│
ā”œā”€ā”€ InputText.jsx
│ └── placeholder
│
└── Button.jsx
└── valor

Cada arquivo possui uma responsabilidade dentro dessa estrutura.

O index.html disponibiliza:

<div id="root"></div>

que representa o ponto no qual a aplicação serÔ montada.

O main.jsx localiza esse elemento:

document.getElementById('root')

cria a raiz React:

createRoot(...)

e renderiza:

<App />

App, por sua vez, utiliza:

<Login />

Finalmente, Login combina os componentes menores responsÔveis pela construção da interface.

Assim, podemos visualizar o processo como:

Documento HTML
│
ā–¼
Inicialização do React
│
ā–¼
Componente Raiz
│
ā–¼
Componente Login
│
ā–¼
Componentes ReutilizƔveis
│
ā–¼
Interface

Componentes de Classe Ɨ Componentes Funcionais​

O exemplo apresentou intencionalmente duas formas de implementação de componentes.

Componentes de Classe​

Foram implementados como Class Components:

Label
Button

Sua estrutura utiliza:

class Componente extends React.Component {
render() {
return (
...
);
}
}

As Props são acessadas, nos exemplos, utilizando:

this.props

Como em:

{this.props.texto}

e:

{this.props.valor}

Componentes Funcionais​

Foram implementados como Function Components:

App
Login
Labelln
InputText

Sua estrutura bÔsica utiliza uma função:

function Componente() {
return (
...
)
}

Em Labelln e InputText, as Props são recebidas utilizando desestruturação:

{ texto }

e:

{ placeholder }

Podemos comparar:

CaracterĆ­sticaClass ComponentFunction Component
Estrutura principalclassfunction
Herança de React.ComponentSimNão
Método render()SimNão
Retorna JSXSimSim
Pode receber PropsSimSim
Acesso utilizado no exemplothis.propsDesestruturação
Exemplo do capĆ­tuloLabel, ButtonApp, Login, Labelln, InputText

Apesar das diferenças estruturais, ambas as formas permitem criar componentes que podem ser utilizados na composição de uma interface.


Props e Reutilização​

As Props foram utilizadas para fornecer informaƧƵes aos componentes.

Em:

<Label texto="UsuƔrio: " />

a Prop:

texto

recebe:

"UsuƔrio: "

JĆ” em:

<InputText placeholder="user..." />

a Prop:

placeholder

recebe:

"user..."

E em:

<Button valor="Logar" />

a Prop:

valor

recebe:

"Logar"

O fluxo apresentado no capĆ­tulo Ć©:

Componente Pai
│
│ Props
ā–¼
Componente Filho

No componente Login, isso fica especialmente evidente:

                     Login
│
ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│ │ │
texto placeholder valor
│ │ │
ā–¼ ā–¼ ā–¼
Label/Labelln InputText Button

A utilização de Props permite modificar informações apresentadas pelos componentes sem modificar sua implementação.


Componentização e Separação de Responsabilidades​

A interface apresentada poderia ser escrita diretamente em um Ćŗnico componente.

Entretanto, o exemplo divide sua construção em:

Label
Labelln
InputText
Button
Login

Cada componente possui uma responsabilidade especĆ­fica.

Essa organização permite compreender que componentização não significa apenas criar vÔrios arquivos.

Os componentes representam partes da interface com responsabilidades próprias.

No exemplo:

Label
└── apresenta texto

Labelln
└── apresenta texto e quebra de linha

InputText
└── apresenta campo de entrada

Button
└── apresenta botĆ£o

Login
└── organiza os componentes

App
└── organiza a interface principal

Essa separação favorece a organização e a reutilização dos componentes.


šŸ’” Dicas do Professor​

Procure compreender a hierarquia antes de analisar componentes isoladamente.

O fluxo index.html → main.jsx → App → Login → componentes ajuda a visualizar como a aplicação Ć© construĆ­da.

Um componente deve possuir uma responsabilidade clara.

No exemplo, InputText representa um campo de entrada, enquanto Button representa um botão. Login possui uma responsabilidade diferente: organizar esses componentes.

Props permitem configurar componentes reutilizƔveis.

O mesmo Label pode apresentar "UsuÔrio: " ou "Senha: " sem que sua implementação seja modificada.

Compare Class Components e Function Components.

O capítulo apresenta as duas estruturas para permitir essa comparação. Observe principalmente render(), this.props e a desestruturação das Props.

Importar um componente não significa utilizÔ-lo na interface.

import disponibiliza o componente no módulo. Ɖ sua utilização no JSX, como <Login />, que o inclui na composição da interface.

Observe o sentido das Props.

Nos exemplos estudados, as informações são fornecidas pelo componente pai e recebidas pelos componentes filhos.

A tela ainda não implementa autenticação.

O objetivo do exemplo é estudar a estrutura do projeto, componentização e Props. Os campos ainda não possuem gerenciamento de estado e o botão não possui comportamento associado ao clique.


šŸ’” Resumo Final​

Neste capítulo estudamos a estrutura bÔsica de uma aplicação ReactJS e acompanhamos o caminho percorrido desde o carregamento do documento HTML até a construção de uma interface composta por diferentes componentes.

O processo comeƧa em:

index.html

Nesse arquivo, o elemento:

<div id="root"></div>

define o ponto de montagem da aplicação.

O arquivo:

main.jsx

Ć© carregado e utiliza:

createRoot(document.getElementById('root'))

para criar uma raiz React associada ao elemento root.

Em seguida, o componente:

<App />

Ć© renderizado.

App funciona como componente raiz da interface e utiliza:

<Login />

O componente Login demonstra a composição de componentes ao reunir:

Label
Labelln
InputText
Button

Durante essa construção, foram apresentadas duas formas de implementação de componentes.

Label e Button foram construĆ­dos como Class Components, utilizando:

extends React.Component

e:

render()

JĆ” App, Login, Labelln e InputText foram apresentados como Function Components.

TambƩm estudamos Props, utilizadas para transmitir informaƧƵes aos componentes.

Por exemplo:

<Label texto="UsuƔrio: " />

fornece a Prop texto ao componente Label.

Em componentes de classe, vimos o acesso utilizando:

this.props.texto

Nos componentes funcionais apresentados, utilizamos desestruturação:

function Labelln({ texto })

A reutilização de Label e InputText com valores diferentes demonstrou como as Props permitem configurar um componente sem alterar sua estrutura.

Assim, o exemplo integrou os conceitos de estrutura de projeto, JSX, modularização, componentes, composição, reutilização e Props na construção de uma interface ReactJS.


šŸ“Œ O que vocĆŖ aprendeu​

Ao concluir este capĆ­tulo, vocĆŖ deverĆ” ser capaz de:

  • identificar os principais arquivos envolvidos na inicialização de uma aplicação ReactJS;
  • compreender o papel do index.html;
  • identificar o elemento utilizado como ponto de montagem da aplicação;
  • compreender a função do arquivo main.jsx;
  • utilizar conceitualmente createRoot() e .render();
  • compreender o papel do componente raiz App;
  • compreender o conceito de JSX;
  • reconhecer componentes pela utilização de nomes iniciados com letra maiĆŗscula;
  • compreender o conceito de Function Component;
  • compreender o conceito de Class Component;
  • identificar o papel de React.Component;
  • compreender a função do mĆ©todo render() em componentes de classe;
  • utilizar fragmentos para agrupar elementos JSX;
  • compreender o funcionamento bĆ”sico de import e export default;
  • compreender o conceito de componentização;
  • compreender a composição entre componentes;
  • identificar relaƧƵes entre componentes pais e filhos;
  • compreender o conceito de Props;
  • acessar Props utilizando this.props nos componentes de classe apresentados;
  • utilizar desestruturação para acessar Props em componentes funcionais;
  • utilizar Props como conteĆŗdo de um componente;
  • utilizar valores recebidos por Props em atributos JSX;
  • compreender como Props favorecem a reutilização de componentes;
  • identificar a responsabilidade dos componentes Label, Labelln, InputText, Button e Login;
  • compreender a hierarquia utilizada para construir a interface apresentada no capĆ­tulo.

šŸ“š ExercĆ­cios de Fixação​