š 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
importeexport; - compreender o conceito de Props;
- transmitir informaƧƵes de um componente pai para um componente filho;
- acessar Props utilizando
this.propsem 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:
| Componente | Responsabilidade |
|---|---|
Label | Exibir pequenos textos utilizados como rótulos. |
Labelln | Exibir textos utilizados na composição da interface. |
InputText | Criar campos de entrada de texto. |
Button | Criar 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,InputTexteButtonsão utilizados porLoginpara 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ā
| Conceito | Explicação |
|---|---|
| ReactJS | Biblioteca utilizada para construção de interfaces a partir de componentes. |
| Componente | Parte da interface que pode ser organizada e reutilizada. |
| Componentização | Divisão da interface em componentes menores. |
| Composição | Utilização de componentes dentro de outros componentes. |
| Componente Raiz | Componente inicial utilizado para organizar a aplicação. No exemplo, App. |
| JSX | Sintaxe utilizada pelos componentes para representar a interface. |
| Class Component | Componente implementado utilizando uma classe que herda de React.Component. |
| Function Component | Componente implementado utilizando uma função. |
| Props | Propriedades utilizadas para transmitir informaƧƵes para componentes. |
import | Permite utilizar em um arquivo recursos definidos em outros módulos. |
export | Permite 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,InputTexteButtonpossuem responsabilidades especĆficas. O componenteLogincombina essas peƧas para formar uma interface maior.
Props tornam os componentes reutilizƔveis.
O mesmo componente
Labelpode apresentar diferentes textos simplesmente recebendo valores diferentes por meio da proptexto.
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ā
| Conceito | Explicação |
|---|---|
index.html | Documento HTML inicial utilizado pela aplicação. |
| HTML5 | Versã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. |
root | Elemento utilizado como ponto de montagem da aplicação React. |
id | Identificador 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 Modules | Sistema de módulos que permite utilizar import e export. |
main.jsx | Arquivo 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
rootcomeç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
rootserĆ” utilizado novamente.Ao estudar
main.jsx, observe como o mesmo nome definido emid="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ā
| Conceito | Explicação |
|---|---|
main.jsx | Arquivo responsÔvel pela inicialização da aplicação React no exemplo. |
StrictMode | Recurso 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. |
root | Identificador do elemento utilizado como ponto de montagem da aplicação. |
.render() | Define o conteĆŗdo que serĆ” renderizado pela raiz React. |
App | Componente raiz utilizado pela aplicação. |
<App /> | Utilização do componente App em JSX. |
index.css | Arquivo utilizado para os estilos globais da aplicação. |
import | Permite utilizar recursos definidos em outros módulos. |
| JSX | Sintaxe utilizada para representar componentes e elementos da interface. |
š” Dicas do Professorā
Relacione
rootnos dois arquivos.O
id="root"definido emindex.htmldeve corresponder ao identificador procurado pordocument.getElementById('root')emmain.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ā
| Conceito | Explicação |
|---|---|
App | Componente raiz da interface utilizado no exemplo. |
| Function Component | Componente React implementado utilizando uma função. |
| JSX | Sintaxe 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. |
| Fragmento | Permite agrupar elementos JSX sem adicionar um elemento extra ao DOM. |
<> </> | Sintaxe simplificada utilizada para criar um fragmento. |
| Componentização | Organização da interface em componentes menores. |
| Composição | Construção de um componente utilizando outros componentes. |
import | Permite utilizar um recurso exportado por outro módulo. |
export default | Define a exportação padrão de um módulo. |
| Componente Raiz | Componente principal a partir do qual a interface Ć© organizada. |
š” Dicas do Professorā
Observe a letra inicial dos componentes.
AppeLogincomeƧam com letra maiĆŗscula. Essa caracterĆstica permite diferenciĆ”-los visualmente de elementos HTML comodiv,inputebutton.
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 porApp.
Appnã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
importeexport.
App.jsxutilizaexport default App, enquantomain.jsxutilizaimport App. Da mesma forma,Login.jsxexportarƔLoginpara queApp.jsxpossa 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ā
| Conceito | Explicação |
|---|---|
| Class Component | Componente implementado utilizando uma classe. |
React.Component | Classe-base utilizada pelo componente Label. |
extends | Estabelece a heranƧa de React.Component. |
render() | MƩtodo que define o JSX apresentado pelo componente de classe. |
| Props | InformaƧƵes recebidas pelo componente. |
this.props | Permite acessar as Props em um componente de classe. |
this.props.texto | Acessa especificamente a Prop texto. |
{ } | Permite inserir uma expressão JavaScript dentro do JSX. |
export default | Define Label como exportação padrão do módulo. |
š” Dicas do Professorā
Observe que
Labelnão define o texto que apresenta.O texto é recebido de outro componente por meio de Props. Isso permite reutilizar
Labelcom diferentes valores.
Em um Class Component, observe o uso de
this.props.Neste exemplo,
this.props.textoacessa a propriedadetextorecebida 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Ćstica | Label | Labelln |
|---|---|---|
| Tipo | Class Component | Function Component |
| Estrutura | class | function |
| Base | React.Component | Função JavaScript |
Método render() | Sim | Não |
| Prop utilizada | texto | texto |
| Acesso Ć Prop | this.props.texto | texto |
| Desestruturação | Não | Sim |
| Retorna JSX | Sim | Sim |
export default | Sim | Sim |
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ā
| Conceito | Explicação |
|---|---|
| Props | Propriedades utilizadas para transmitir informaƧƵes para um componente. |
| Componente Pai | Componente que utiliza outro componente e fornece suas Props. |
| Componente Filho | Componente que recebe as Props. |
| Class Component | Componente implementado por meio de uma classe. |
| Function Component | Componente implementado por meio de uma função. |
React.Component | Classe-base utilizada na implementação de Label. |
render() | MƩtodo utilizado pelo Class Component para retornar JSX. |
this.props | Forma utilizada no exemplo para acessar Props no componente de classe. |
| Desestruturação | Recurso 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ção | Possibilidade de utilizar o mesmo componente com diferentes valores de Props. |
š” Dicas do Professorā
Compare os dois componentes, não apenas seus resultados.
LabeleLabellnrecebem uma Prop chamadatexto, 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 propriedadetexto.
Observe a desestruturação em
Labelln.
{ texto }no parâmetro permite utilizar diretamentetextodentro da função, evitando a escritaprops.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
LabelserÔ 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ā
| Conceito | Explicação |
|---|---|
| Function Component | Componente implementado utilizando uma função. |
| Props | InformaƧƵes recebidas pelo componente. |
placeholder | Prop utilizada para configurar o texto de orientação do campo. |
| Desestruturação | Permite 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 controlado | Campo cujo valor não estÔ sendo gerenciado por um estado React no exemplo. |
| Reutilização | Permite utilizar o mesmo InputText com diferentes valores de placeholder. |
š” Dicas do Professorā
Observe onde a Prop estĆ” sendo utilizada.
Em
Labelln,textoaparece como conteúdo do componente. EmInputText,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,
InputTexttem 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Ćstica | InputText | Button |
|---|---|---|
| Tipo | Function Component | Class Component |
| Estrutura | function | class |
| Prop utilizada | placeholder | valor |
| Acesso Ć Prop | placeholder | this.props.valor |
| Desestruturação | Sim | Não |
Método render() | Não | Sim |
| Elemento retornado | <input> | <button> |
export default | Sim | Sim |
| ReutilizƔvel | Sim | Sim |
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:
| Componente | Tipo | Prop | Responsabilidade |
|---|---|---|---|
Label | Class Component | texto | Apresentar um texto utilizado como rótulo. |
Labelln | Function Component | texto | Apresentar um texto seguido de uma quebra de linha. |
InputText | Function Component | placeholder | Apresentar um campo de entrada de texto. |
Button | Class Component | valor | Apresentar 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ā
| Conceito | Explicação |
|---|---|
| Function Component | Forma utilizada para implementar InputText. |
| Class Component | Forma utilizada para implementar Button. |
| Props | InformaƧƵes fornecidas aos componentes. |
| Desestruturação de Props | Forma utilizada por InputText para acessar placeholder. |
this.props | Forma utilizada por Button para acessar suas Props. |
placeholder | Prop utilizada para configurar o campo de entrada. |
valor | Prop 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. |
| JSX | Permite combinar elementos e expressƵes JavaScript na interface. |
| Input não controlado | Campo cujo valor não é gerenciado por estado no exemplo. |
| Reutilização | Possibilidade de utilizar os componentes com diferentes valores de Props. |
| Componentização | DivisĆ£o da interface em componentes com responsabilidades especĆficas. |
š” Dicas do Professorā
Observe como as Props tornam os componentes configurƔveis.
InputTextnão precisa saber antecipadamente qual texto deverÔ aparecer comoplaceholder, assim comoButtonnão precisa saber qual texto deverÔ apresentar.
Compare novamente Function Component e Class Component.
InputTextrecebeplaceholderpor desestruturação, enquantoButtonutilizathis.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,
InputTextrepresenta um campo de entrada eButtonrepresenta 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.jsxreunirÔLabel,Labelln,InputTexteButton, 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:
| Componente | Prop | Valor utilizado no exemplo |
|---|---|---|
Labelln | texto | "Login" |
Label | texto | "UsuƔrio: " |
InputText | placeholder | "user..." |
Label | texto | "Senha: " |
InputText | placeholder | "password..." |
Button | valor | "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ā
| Conceito | Explicação |
|---|---|
Login | Function Component responsƔvel por organizar a interface apresentada no exemplo. |
| Componente Pai | Componente que utiliza e fornece Props para outros componentes. |
| Componente Filho | Componente utilizado por outro componente e que pode receber Props. |
| Props | InformaƧƵes transmitidas para configurar componentes. |
| Composição | Construção de uma interface por meio da combinação de componentes. |
| Reutilização | Utilização do mesmo componente mais de uma vez com diferentes Props. |
| Modularização | Organização dos componentes em arquivos separados. |
import | Torna os componentes exportados disponĆveis em Login.jsx. |
export default | Disponibiliza Login para utilização em outro módulo. |
| Fragmento | Agrupa os elementos retornados por Login sem adicionar uma <div> extra. |
texto | Prop utilizada pelos componentes Label e Labelln. |
placeholder | Prop utilizada por InputText. |
valor | Prop utilizada por Button. |
| Separação de Responsabilidades | Distribuiçã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: " />,Loginfornece a Proptexto, enquantoLabelƩ 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,
Labelpode 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 ā componentesajuda 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:
| Conceito | Explicação |
|---|---|
index.html | Documento HTML inicial que disponibiliza o ponto de montagem da aplicação React. |
root | Elemento HTML no qual a interface React Ć© montada. |
main.jsx | Arquivo 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. |
StrictMode | Recurso utilizado durante o desenvolvimento para auxiliar na identificação de possĆveis problemas. |
App | Componente raiz da interface apresentado no exemplo. |
| Componente | Parte da interface que possui uma responsabilidade especĆfica e pode ser combinada com outros componentes. |
| Componentização | Divisão da interface em componentes menores. |
| Composição | Construção de componentes maiores utilizando componentes menores. |
| Reutilização | Utilização do mesmo componente em diferentes situações, alterando sua configuração por meio de Props. |
| JSX | Sintaxe utilizada para representar elementos e componentes dentro do código JavaScript. |
| Fragmento | Permite agrupar elementos JSX sem adicionar um elemento HTML adicional ao DOM. |
<> </> | Sintaxe simplificada utilizada para representar um fragmento. |
| Function Component | Componente React implementado utilizando uma função. |
| Class Component | Componente React implementado utilizando uma classe que herda de React.Component. |
React.Component | Classe-base utilizada pelos componentes de classe apresentados no capĆtulo. |
render() | MƩtodo utilizado pelos Class Components para retornar JSX. |
| Props | Informações fornecidas a um componente para configurar sua utilização. |
this.props | Forma utilizada nos componentes de classe do exemplo para acessar Props. |
| Desestruturação de Props | Recurso utilizado nos componentes funcionais para acessar diretamente propriedades recebidas. |
import | Permite utilizar recursos disponibilizados por outros módulos. |
export default | Define a exportação padrão de um módulo. |
| Modularização | Organizaçã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Ćstica | Class Component | Function Component |
|---|---|---|
| Estrutura principal | class | function |
Herança de React.Component | Sim | Não |
Método render() | Sim | Não |
| Retorna JSX | Sim | Sim |
| Pode receber Props | Sim | Sim |
| Acesso utilizado no exemplo | this.props | Desestruturação |
| Exemplo do capĆtulo | Label, Button | App, 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 ā componentesajuda a visualizar como a aplicação Ć© construĆda.
Um componente deve possuir uma responsabilidade clara.
No exemplo,
InputTextrepresenta um campo de entrada, enquantoButtonrepresenta um botão.Loginpossui uma responsabilidade diferente: organizar esses componentes.
Props permitem configurar componentes reutilizƔveis.
O mesmo
Labelpode 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.propse a desestruturação das Props.
Importar um componente não significa utilizÔ-lo na interface.
importdisponibiliza 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
importeexport 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.propsnos 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,ButtoneLogin; - compreender a hierarquia utilizada para construir a interface apresentada no capĆtulo.