Apostila React

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

A biblioteca React.js foi lançada em 2013 pelo Facebook. Seu foco não é ser um framework completo como o Angular e sim ser somente o “V” do MVC (Model View Controller) focando apenas na criação de componentes visuais.

O que é?

O React é uma biblioteca para criação de interface e representa a camada de “View” em um modelo de projeto. Essa camada de visualização é criada a partir de componentes que representam funcionalidades isoladas em um sistema. Desenvolvida e disponibilizada pelo Facebook, o React é uma lib de código aberto e é mantida por milhares de desenvolvedores ao redor do mundo que contribuem de forma voluntária ao projeto.

O ReactJS foi criado pelo Facebook e inicialmente lançado como código aberto em maio de 2013. A história por trás do React é interessante, pois reflete os desafios e as necessidades específicas enfrentadas pelo Facebook na época.

O Facebook, como uma das maiores redes sociais do mundo, enfrentava o desafio de lidar com interfaces complexas e dinâmicas, como o feed de notícias, comentários em tempo real, atualizações constantes de conteúdo e interações de usuário rápidas e fluidas. Essas demandas exigiam uma abordagem mais eficiente para renderização de interfaces de usuário em tempo real, especialmente em dispositivos móveis.

A ideia do React surgiu como uma resposta a esses desafios. Jordan Walke, um engenheiro do Facebook, foi o principal criador do React. Ele começou a trabalhar em uma biblioteca interna chamada "FaxJS" para melhorar a renderização de interfaces de usuário no Facebook. Mais tarde, esse projeto evoluiu para o que conhecemos hoje como React.

O React introduziu conceitos inovadores, como a manipulação eficiente do DOM por meio da virtualização, o uso de componentes reutilizáveis e a abordagem declarativa para construir interfaces de usuário. Esses conceitos permitiram que os desenvolvedores criassem aplicativos mais rápidos, escaláveis e fáceis de manter.

Com o tempo, o React ganhou popularidade não apenas dentro do Facebook, mas também na comunidade de desenvolvedores externos. O Facebook lançou o React como código aberto em 2013, permitindo que desenvolvedores de todo o mundo utilizassem e contribuíssem para a evolução da biblioteca.

Atualmente, o React é uma das bibliotecas JavaScript mais populares e amplamente utilizadas para o desenvolvimento de interfaces de usuário modernas e interativas em aplicações web e móveis. Sua comunidade ativa, documentação abrangente e suporte contínuo de desenvolvimento o tornaram uma escolha preferida para muitos desenvolvedores e empresas.

Em 2015, o Facebook anunciou o módulo React Native, que em conjunto com o React, possibilita o desenvolvimento de aplicativos para Android e iOS utilizando componentes de interface de usuário nativos de ambas plataformas, sem precisar recorrer ao HTML.

Declarativo

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

React faz com que a criação de UIs interativas seja uma tarefa fácil. Crie views simples para cada estado na sua aplicação, e o React irá atualizar e renderizar de forma eficiente apenas os componentes necessários na medida em que os dados mudam.

Views declarativas fazem com que seu código seja mais previsível e simples de depurar.

Componentização

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Baseado em componentes

Crie componentes encapsulados que gerenciam seu próprio estado e então, combine-os para criar UIs complexas.
Como a lógica do componente é escrita em JavaScript e não em templates, você pode facilmente passar diversos tipos de dados ao longo da sua aplicação e ainda manter o estado fora do DOM.

Os componentes do React implementam um método render() que recebe os dados de entrada e retornam o que deve ser exibido. Este exemplo usa uma sintaxe parecida com XML chamada JSX. Os dados de entrada que são passados para o componente podem ser acessados no render() via this.props.

A principal diferença do React e de outras bibliotecas baseadas em componentes diante de libs como o jQuery, Angular 1 ou Javascript puro está em sua habilidade de separar as funcionalidades do software em componentes, mas o que são componentes?

Componentes são conjuntos isolados de lógica (Javascript), visualização (JSX/HTML) e possível estilização (CSS).

Imagine a timeline do Facebook (grande case que originou o React), você roda a barra de rolagem até conter 500 posts em tela e então adiciona um comentário ao post de nº 250, imagine o quão trabalhoso é para a DOM do seu navegador entender que um único elemento no meio de tantos foi atualizado e enviar essa informação em tempo-real para os outros usuários do Facebook, ou até ouvir a atualização de 500 posts em tela de forma organizada, imagine controlar tudo isso com jQuery ou Javascript puro, será que é possível?

Separando os posts em componentes, cada item controla suas próprias informações e assim quando uma dessas publicações sofre alteração, seja comentário ou atualização em tempo real, a única que ela enxerga é a si mesmo e não precisa varrer toda DOM procurando pelo item correto a se atualizar.

Utilizando o conceito de componente, vamos visualizar a conversão dessa interface abaixo em componentes:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Veja que tudo que é visível ao usuário final da aplicação é obrigatoriamente um componente e os dividimos de forma a encapsular a lógica e estilização do mesmo, assim evitando o compartilhamento desnecessário de código entre outros componentes.

Os componentes do React implementam um método render() que recebe os dados de entrada e retornam o que deve ser exibido. Este exemplo usa uma sintaxe parecida com XML chamada JSX. Os dados de entrada que são passados para o componente podem ser acessados no render() via this.props.

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

SPA – Single Page Application

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Basicamente uma aplicação SPA significa você codificar menos no server-side e mais no client-side, mas como isso? A aplicação estará quase toda no cliente, sendo que assim que o usuário acesso o site a aplicação e seus templates são armazenados no lado cliente, muito diferente da forma tradicional, onde o usuário visita várias páginas diferentes.

As aplicações e os sites SPA, fazem uma transição entre os templates carregados, sem reload de página e sem que o usuário viaje de uma página para outra.

ECMA Script 6

O ECMAScript (ES) é a especificação da linguagem de script que o JavaScript implementa, ou seja, é a descrição formal e estruturada de uma linguagem de script, sendo padronizada pela Ecma International – associação criada em 1961 dedicada à padronização de sistemas de informação e comunicação – na especificação ECMA-262. No dia 17 de junho de 2015, foi definida a sexta edição da especificação, a ES6 (também chamada de ECMAScript 2015).

Diferentemente das edições anteriores, o ES6 trouxe a maior mudança para a linguagem JavaScript desde a sua criação, há 20 anos. O principal objetivo da nova versão especificação foi tornar a linguagem mais flexível, enxuta e fácil de se aprender e trabalhar, tornando-a mais próxima a outras linguagens orientadas a objeto, como Java e Python.

Comandos básicos

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
PARA INSTALAR O REACT:

npm install -g create-react-app

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
PARA CRIAR PROJETO:

create-react-app nome_do_projeto npx create-react-app projeto01

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
PARA MUDAR A PORTA no package.json

"scripts": { "start": "set PORT=3006 && PORT=3006 react-scripts start || react-scripts start",

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
PARA RODAR O PROJETO:

npm start

No terminal:

Compiled successfully!

You can now view <project_name> in the browser.

  Local:            http://localhost:3000/
  On Your Network:  http://<your_ip_address>:3000/

Note that the development build is not optimized.
To create a production build, use yarn build.

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
PARA SABER A VERSÃO INSTALADA NA MAQUINA:

create-react-app --version

Componentes Funcionais

Os componentes funcionais tem como função receber um objeto “props” como argumento e retornar um elemento React sem se importar com o estado da aplicação. Esse tipo de componente é chamado de funcional porque é basicamente uma função JavaScript. Um componente funcional também é chamado de “apresentacional”, “mudo” ou “sem estado”.

import React from 'react'; const person = () => { return <h1>Person Name</h1> }; export default person;

Componentes de Classe

Os componentes de classe precisam estar cientes do estado da aplicação, de acordo com determinada ação do usuário(como clicar em um botão) o componente deve responder de alguma forma. O componente de classe também é conhecido como “container”, “smart” ou “stateful”.

import React, { Component } from 'react'; class Person extends Component { render() { return ( <h1>Person Name!</h1> ); } } export default Person;

Props

Props é um objeto passado por um componente pai para um componente filho, e contém todas as informações relevantes para aquele componente.

Estado

O estado de um componente React é um objeto JavaScript responsável por armazenar e reagir aos eventos do usuário. Todo componente de classe tem seu próprio objeto de estado possibilitando assim, sempre que o estado de um componente for alterado, o componente e seus filhos serão renderizados novamente.

Para inicializarmos o estado inicial de um componente de classe, fazemos a definição no método construtor e para acessar o estado usamos this.state:

import React, { Component } from 'react'; class Person extends Component { constructor(props) { super(props); this.state = {name: 'Thiago'} } render() { return ( <h1>Person Name: {this.state.name}</h1> ); } } export default Person;

Quando o componente possui um método construtor, é obrigatória a chamada ao método super(), pois o componente é uma subclasse da classe Component. Para usar this.props no contexto do método construtor é preciso passar props como parâmetro para o método super().

Store:

é o container que armazena e centraliza o estado geral da aplicação. Ela é imutável, ou seja, nunca se altera, apenas evolui.

Actions:

são fontes de informações que são enviadas da aplicação para a Store. São disparadas pelas Action Creators, que são simples funções que, ao serem executadas, ativam os Reducers.

Reducers:

recebem e tratam as informações para que sejam ou não enviadas à Store.

Conexão dos componentes ao Redux:

para poderem se inscrever à evolução de estados da Store ou disparar eventos para evoluí-la.

Ciclo de Vida

Nos componentes React é possível declarar métodos que serão chamados automaticamente em certas ocasiões durante o ciclo de vida. Para entendermos todo o ciclo de vida, é preciso diferenciar as ações ocorridas em cada fase como a fase de criação, mudança no estado e mudança no objeto props.

Ciclo de Montagem

Ciclo de Desmontagem

Ciclo com mudança em props

Ciclo com mudança no state

O fluxo de mudança de estado é praticamente o mesmo fluxo disparado pelas alterações em props, com exceção que não há uma chamada ao método componentWillReceiveProps. Alterações em props podem causar uma mudança no state, mas o oposto não pode ocorrer. Se for preciso executar operações após uma mudança de estado devemos utilizar o método componentWillUpdate.

Algumas bibliotecas:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
react-router-dom
Biblioteca para auxiliar no gerenciamento de rotas da sua aplicação;

npm i react-router-dom --save

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
redux-form:
Gerenciamento de estado em formulários no redux;

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
redux-saga:
Gerenciamento de requisições e ações assíncronas da aplicação (ex. requisição de dados de uma API);

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
axios:
Biblioteca que auxilia em requisições HTTP;

npm install axios

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
popper (bootstrap):

npm i popper.js --save

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
bootstrap:

npm i bootstrap --save

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
jquery:

npm i jquery --save

Redux

O Redux simplifica a evolução de estados de uma aplicação quando há múltiplos estados para controlar e muitos componentes que precisam atualizar ou se inscrever nessa evolução, tirando a responsabilidade de cada componente de guardar o estado e passando para uma centralizada e única Store.

Fluxo de evolução de estado

Store:

é o container que armazena e centraliza o estado geral da aplicação. Ela é imutável, ou seja, nunca se altera, apenas evolui.

Actions:

são fontes de informações que são enviadas da aplicação para a Store. São disparadas pelas Action Creators, que são simples funções que, ao serem executadas, ativam os Reducers.

Reducers:

recebem e tratam as informações para que sejam ou não enviadas à Store.

Conexão dos componentes ao Redux:

para poderem se inscrever à evolução de estados da Store ou disparar eventos para evoluí-la.

Redux Forms

Biblioteca React para desenvolvimento de formulários através do Redux. É capaz de integrar as ações de formulário ao state da aplicação, incluir recursos de validação, etc.

formReducer
Reducer da biblioteca Redux-Forms que irá modificar a store sempre que um evento (action) de formulário for disparado

reduxForm()
Habilita o componente a utilizar a biblioteca Redux-Form

<Field/>
Componente que será utilizado para desenvolver os campos do formulário.

Ciclo de vida do React-Redux

Modificando o valor da store através dos reducers:

Acessando dados de uma API no Redux:

Redux Saga

Redux-saga é uma biblioteca que foca em fazer os efeitos colaterais (ex: chamadas assíncronas para buscar dados em uma API, acessar o cache do navegador, etc) em aplicações React/Redux serem mais fáceis e simples de se criar e manter.

Redux Saga expõe vários métodos chamados de Effects, e vamos usar vários deles:

Metodos Descrição
fork(), realiza uma operação não bloqueante com a função passada
take(), pausa as operações até receber uma redux action
race(), executa Effects simultaneamente, e cancela todos quando um efeito retorna seu resultado
call(), executa uma função. Se essa função retornar uma Promise, ele irá pausar a Saga até a Promise ser resolvida
put(), despacha uma redux action
select(), executa uma função seletora que irá buscar dados do estado global do Redux
takeLatest(), irá executar as operações recebidas, porém, irá retornar apenas o valor da última. Se a mesma operação for enviada mais de uma vez, elas serão ignoradas, exceto a última (ex: click -> loadUser, usuário clica 4 vezes no botão (ele é legal né, quer testar sua app), apenas a função enviada no último click será executada/retornado o valor, as outras serão ignoradas)
takeEvery(), irá retornar os valores de todas as operações recebidas

Testes Automatizados com React

JEST (https://jestjs.io/docs/en/tutorial-react)

ENZYME (https://airbnb.io/enzyme/)

prop-types (https://fettblog.eu/typescript-react/prop-types/)

Surge (https://surge.sh/)

Publicando o projeto (Build)

npm install -g surge

Gerando o build do projeto:

npm run build

Instalando o servidor local para executar o build:

npm install -g serve serve -s build

Publicando no servidor surge

cd build surge

.
.
.

Bibliotecas de Estilos Css:

No ecossistema ReactJS, algumas das bibliotecas de estilos mais utilizadas são:

  1. Styled-components: Esta é uma biblioteca muito popular para estilizar componentes React usando CSS-in-JS. Ela permite escrever estilos CSS diretamente no JavaScript, o que facilita o encapsulamento de estilos junto com a lógica dos componentes. É amplamente adotada pela sua facilidade de uso e flexibilidade.

  2. Material-UI: Baseado no design de materiais do Google, o Material-UI é uma biblioteca de componentes React que oferece uma variedade de elementos de interface de usuário estilizados, como botões, cards, barras de navegação, entre outros. É uma escolha popular devido à sua extensa documentação e à vasta coleção de componentes prontos para uso.

  3. Ant Design: Desenvolvido pela equipe da Ant Financial (Alibaba), o Ant Design é uma biblioteca de componentes React com um conjunto rico de elementos de interface de usuário, seguindo os padrões de design da Ant Financial. É muito utilizado em aplicações empresariais e possui uma ampla gama de componentes customizáveis.

  4. Bootstrap: Embora seja mais conhecido por sua integração com o jQuery, o Bootstrap também oferece uma versão específica para React chamada React-Bootstrap. Ele fornece componentes React que seguem as diretrizes visuais e de interação do Bootstrap, facilitando a criação de layouts responsivos e modernos.

  5. Chakra UI: Esta é uma biblioteca relativamente nova, mas ganhando rapidamente popularidade devido à sua ênfase na acessibilidade, responsividade e facilidade de uso. Chakra UI oferece uma variedade de componentes estilizados e temas customizáveis para criar interfaces consistentes e acessíveis.

.
.
.

Frameowrks de Testes no ReactJs:

Os frameworks mais utilizados para testes no ecossistema React e no desenvolvimento de aplicações web em geral incluem:

  1. Jest: O Jest é um dos frameworks de teste mais populares para JavaScript. Ele é amplamente utilizado para testes unitários, testes de integração e testes de snapshot em aplicações React. O Jest é conhecido pela sua simplicidade de uso, configuração fácil e suporte a recursos avançados como mocks e spies.

  2. React Testing Library: Este não é exatamente um framework de teste, mas uma biblioteca de utilitários para testar componentes React. Ela é projetada para promover boas práticas de testes e interações de usuário realistas. A React Testing Library é comumente usada em conjunto com o Jest para testes de componentes React.

  3. Enzyme: O Enzyme é outra biblioteca popular para testes de componentes React. Ele fornece utilitários para manipular, simular eventos e testar componentes de forma isolada. Embora o Enzyme seja amplamente utilizado, o time do React recomenda o uso da React Testing Library para novos projetos.

  4. Cypress: O Cypress é uma ferramenta de teste end-to-end (E2E) que permite testar aplicações web em um ambiente de navegador real. Ele é usado para testes de integração e testes de ponta a ponta, simulando interações do usuário e verificando o comportamento da aplicação em um ambiente real.

  5. Performance Testing Frameworks:

    • Lighthouse: Não é exatamente um framework, mas uma ferramenta de teste de desempenho desenvolvida pelo Google. O Lighthouse é usado para analisar a performance de aplicações web, fornecendo métricas e sugestões de otimização.
    • WebPagetest: É uma ferramenta gratuita e de código aberto para testar o desempenho de sites em diferentes dispositivos e conexões de internet. Ele oferece métricas detalhadas e simulações de carregamento de página em condições reais.
      .
      .
      .

.
.
.

Projetos ReactJs

Comandos:

  • Instalação do ReactJs: npm install -g create-react-app
  • Para criar um projeto: npx create-react-app nome_do_projeto
  • Para rodar o projeto: npm start
  • Para saber a versão do ReactJS: create-react-app --version

Estrutura baisca:

meu-projeto/
├── public/
│   ├── index.html
│   └── ...
├── src/
│   ├── assets/
│   │   └── imagens/
│   │   └── estilos/
│   │       └── estilos.css
│   ├── components/
│   │   ├── FormularioUsuarios.js
│   │   └── ListaUsuarios.js
│   ├── models/
│   │   └── Usuario.js
│   ├── services/
│   │   └── UsuarioService.js
│   ├── App.js
│   └── index.js
├── node_modules/
├── package.json
└── README.md

.
.
.

Aula 01 - Listar com css

package.json

{ "name": "projeto", "version": "0.1.0", "private": true, "dependencies": { "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-scripts": "5.0.1", "web-vitals": "^2.1.4" }, "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject" }, "eslintConfig": { "extends": [ "react-app", "react-app/jest" ] }, "browserslist": { "production": [ ">0.2%", "not dead", "not op_mini all" ], "development": [ "last 1 chrome version", "last 1 firefox version", "last 1 safari version" ] } }

App.js

import './App.css'; import React, { useState } from 'react'; const style = { table: { borderCollapse: 'collapse' }, tableCell: { border: '1px solid gray', margin: 0, padding: '5px 10px', width: 'max-content', minWidth: '150px' }, form: { container: { padding: '20px', border: '1px solid #F0F8FF', borderRadius: '15px', width: 'max-content', marginBottom: '40px' }, inputs: { marginBottom: '5px' }, submitBtn: { marginTop: '10px', padding: '10px 15px', border: 'none', backgroundColor: 'lightseagreen', fontSize: '14px', borderRadius: '5px' } } } function UsuariosForm({ addUsuarios }) { const [nome, setNome] = useState(""); const [email, setEmail] = useState(""); const [celular, setCelular] = useState("") const handleSubmit = (e) => { e.preventDefault(); addUsuarios({ nome, email, celular }); setNome(''); setEmail(''); setCelular(''); } return ( <form onSubmit={handleSubmit} style={style.form.container}> <label>Nome:</label> <br /> <input style={style.form.inputs} className='nome' name='nome' type='text' value={nome} onChange={(e) => setNome(e.target.value)} /> <br /> <label>E-mail:</label> <br /> <input style={style.form.inputs} className='email' name='email' type='text' value={email} onChange={(e) => setEmail(e.target.value)} /> <br /> <label>Celular:</label> <br /> <input style={style.form.inputs} className='celular' name='celular' type='text' value={celular} onChange={(e) => setCelular(e.target.value)} /> <br /> <input style={style.form.submitBtn} className='submitButton' type='submit' value='Adicionar' /> </form> ) } function ListaTable({ addUsuarios }) { return ( <table style={style.table} className='listaTable'> <thead> <tr> <th style={style.tableCell}>Nome</th> <th style={style.tableCell}>E-mail</th> <th style={style.tableCell}>Celular</th> </tr> </thead> <tbody> {addUsuarios.map((entry, index) => ( <tr key={index}> <td style={style.tableCell}>{entry.nome}</td> <td style={style.tableCell}>{entry.email}</td> <td style={style.tableCell}>{entry.celular}</td> </tr> ))} </tbody> </table> ); } function App(props) { const [usuario, setUsuarios] = useState([]); const addUsuarios = (entry) => { setUsuarios([...usuario, entry]); }; return ( <section> <UsuariosForm addUsuarios={addUsuarios} /> <ListaTable addUsuarios={usuario} /> </section> ); } export default App;

index.js

import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css'; import App1 from './App1'; import reportWebVitals from './reportWebVitals'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <React.StrictMode> <App /> </React.StrictMode> ); reportWebVitals();

.
.
.

Projeto 2 - Listar com Bootstrap

Instalar:

  • Instalação do jquery: npm install jquery
  • Instalação do Bootstrap: npm install bootstrap

package.json

{ "name": "projeto", "version": "0.1.0", "private": true, "dependencies": { "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", "bootstrap": "^5.3.3", "jquery": "^3.7.1", "react": "^18.2.0", "react-dom": "^18.2.0", "react-scripts": "5.0.1", "web-vitals": "^2.1.4" }, "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject" }, "eslintConfig": { "extends": [ "react-app", "react-app/jest" ] }, "browserslist": { "production": [ ">0.2%", "not dead", "not op_mini all" ], "development": [ "last 1 chrome version", "last 1 firefox version", "last 1 safari version" ] } }

App1.js

import './App1.css'; import React, { useState } from 'react'; // FORMULARIO function UsuariosForm({ addUsuarios }) { // SETA OS CAMPOS const [nome, setNome] = useState(""); const [email, setEmail] = useState(""); const [celular, setCelular] = useState(""); const [foto, setFoto ] = useState(""); // CONSTRUTOR const handleSubmit = (e) => { e.preventDefault(); addUsuarios({ nome, email, celular, foto }); // LIMPA OS CAMPOS APOS ADICIONAR setNome(''); setEmail(''); setCelular(''); setFoto(''); } // DESIGN DO FORMULARIO return ( <form onSubmit={handleSubmit} className="card col-md-6 offset-md-3 mt-5 shadow"> <div className='card-header text-center'> <h2>Formulário de Cadastro</h2> </div> <div className='card-body'> <div className="form-group"> <label>Nome:</label> <input className="form-control" type="text" value={nome} onChange={(e) => setNome(e.target.value)} /> </div> <div className="form-group"> <label>E-mail:</label> <input className="form-control" type="text" value={email} onChange={(e) => setEmail(e.target.value)} /> </div> <div className="form-group"> <label>Celular:</label> <input className="form-control" type="text" value={celular} onChange={(e) => setCelular(e.target.value)} /> </div> <div className="form-group"> <label>Foto:</label> <input className="form-control" type="text" value={foto} onChange={(e) => setFoto(e.target.value)} /> </div> <button className="btn btn-primary mt-3">Adicionar</button> </div> </form> ) } // LISTA RESGATA OS DADOS DO ADDUSUSARIOS DO CONSTRUTOR function ListaTable({ addUsuarios }) { return ( <table className='table table-bordered table-hover mt-5'> <thead className='text-center text-uppercase'> <tr> <th>Foto</th> <th>Nome</th> <th>E-mail</th> <th>Celular</th> </tr> </thead> <tbody> {addUsuarios.map((entry, index) => ( <tr key={index}> <td><img src={entry.foto} className='img-thumbnail imagem-redimensionada img-responsive shadow'/></td> <td>{entry.nome}</td> <td>{entry.email}</td> <td>{entry.celular}</td> </tr> ))} </tbody> </table> ); } function App1() { const [usuario, setUsuarios] = useState([]); const addUsuarios = (entry) => { setUsuarios([...usuario, entry]); }; // CHAMA OS COMPONENTES return ( <section className="container"> <UsuariosForm addUsuarios={addUsuarios} /> <ListaTable addUsuarios={usuario} /> </section> ); } export default App1;

App1.css

.imagem-redimensionada { width: 100px ; height: auto; }

index.js
Anotar o Bootstrap e o Jquery

import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css'; import App1 from './App1'; import reportWebVitals from './reportWebVitals'; import 'bootstrap/dist/css/bootstrap.min.css'; import 'jquery/dist/jquery.min.js'; import 'bootstrap/dist/js/bootstrap.bundle.min.js'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <React.StrictMode> <App1 /> </React.StrictMode> ); reportWebVitals();

image