
Passo a passo na construção de exemplo em React
O que você precisa saber de React para falar que sabe algo, um um pouco
Biblioteca React criada para facilitar a criação de aplicativos para execução no navegador
Pré-requisitos
Para começar precisamos dos softwares
- Node, podemos verificar a instalação pelo comando
node -v; - NPM, podemos verificar a instalação pelo comando
npm -v; - Qualquer IDE com suporte a JavaScript recomendo VSCode.
Instalar a ferramenta de auxílio para configuração das ferramenta de construção
yarn global add create-react-app
# or
npm -g i create-react-appIniciar projeto pela ferramenta de auxílio
npx create-react-app medals-olympic
cd medals-olympic
yarn startProjeto vai estar disponível em localhost:3000
Rotas
- Simulação de rotas;
- Redesenho do DOM.
Instalação da biblioteca react-router-dom para controle de rotas
yarn add react-router-dom
# or
npm i react-router-domCriar o arquivo src/routes/Medals.jsx dentro da pasta indicada, para com o caminho da rota de medalhas
import React from "react"
const Medals = () => {
return <h1>Medalhas</h1>
}
export default MedalsCriar o arquivo src/routes/Teams.jsx para com o caminho da rota de times
import React from "react"
const Teams = () => {
return <h1>Time</h1>
}
export default TeamsAlterar o arquivo src/Apps.js para aceitar as rotas criadas
import { BrowserRouter as Router, Route, Routes } from "react-router-dom"
import Medals from "./routes/Medals"
import Teams from "./routes/Teams"
function App() {
return (
<Router>
<div>
<Routes>
<Route path="/:team" element={<Teams />} />
<Route path="/" element={<Medals />} />
</Routes>
</div>
</Router>
)
}
export default AppCom o comando yarn start podemos visualizar a resposta pelo localhost:3000 apresentando a rota medals e localhost:3000/sweden para apresentar a rota de teams, podemos substituir o sweden por qualquer conteúdo
Componentes
- Separação de responsabilidades;
- Propriedades de componentes;
- Desenho no DOM.
Criar o arquivo src/components/Header/index.jsx com o conteúdo do que irá se apresentar no topo de todas as telas
import React from "react"
const Header = () => {
return (
<header>
<h1>Header</h1>
</header>
)
}
export default HeaderCriar o arquivo src/components/Footer/index.jsx com o conteúdo do que irá se apresentar no rodapé de todas as telas
import React from "react"
const Footer = () => {
return (
<footer>
<h1>Footer</h1>
</footer>
)
}
export default FooterCriar o arquivo src/components/Main/index.jsx, que irá encapsular as informações das rotas, destaque para o children que é todo conteúdo dentro das tags do componente
import React from "react"
const Main = ({ children }) => {
return <main>{children}</main>
}
export default MainAlterar o arquivo src/Apps.js com destaque para a importação e adição do Header e Footer dentro da tag Router
import { BrowserRouter as Router, Route, Routes } from "react-router-dom"
import Footer from "./components/Footer"
import Header from "./components/Header"
import Main from "./components/Main"
import Medals from "./routes/Medals"
import Teams from "./routes/Teams"
function App() {
return (
<Router>
<Header />
<Main>
<Routes>
<Route path="/:team" element={<Teams />} />
<Route path="/" element={<Medals />} />
</Routes>
</Main>
<Footer />
</Router>
)
}
export default AppCom o comando yarn start podemos visualizar a resposta pelo localhost:3000 com o conteúdo do header e footer em todos os caminhos
Estilos
- Construção das classes;
- Alteração do
head.
Instalação da biblioteca styled-components que facilitará o uso de CSS para os componentes
yarn add styled-components
# or
npm i styled-componentsCriar o arquivo src/globalStyles.js com o CSS Reset, setando as configurações padrão para estilos para o projeto
import { createGlobalStyle } from "styled-components"
const GlobalStyle = createGlobalStyle`
*,
*:before,
*:after {
margin: 0;
padding: 0;
outline: 0;
box-sizing: border-box;
}
html {
font-size: 62.5%;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
}
a,
a:hover,
a:visited {
text-decoration: none;
color: inherit;
}
`
export default GlobalStyleAlterar o arquivo src/Apps.js para adicionar a importação e o componente de GlobalStyle
import { BrowserRouter as Router, Route, Routes } from "react-router-dom"
import Footer from "./components/Footer"
import Header from "./components/Header"
import Main from "./components/Main"
import Medals from "./routes/Medals"
import Teams from "./routes/Teams"
import GlobalStyle from "./globalStyles"
function App() {
return (
<Router>
<GlobalStyle />
<Header />
<Main>
<Routes>
<Route path="/:team" element={<Teams />} />
<Route path="/" element={<Medals />} />
</Routes>
</Main>
<Footer />
</Router>
)
}
export default AppCriar o arquivo src/components/Header/styles.js
import styled from "styled-components"
export const Wrapper = styled.header`
height: 8rem;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
`
export const Content = styled.div`
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
padding-left: calc((100vw - 98rem) / 2);
`
export const Logo = styled.img`
height: 6rem;
`
export const Title = styled.h1`
margin-left: 2rem;
color: #444;
text-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25);
`
export const Back = styled.img`
height: 8rem;
`Alterar o arquivo src/components/Header/index.jsx
import React from "react"
import { Wrapper, Content, Logo, Title, Back } from "./styles"
const Header = () => {
return (
<Wrapper>
<Content>
<Logo src="https://olympics.com/en/images/static/beijing-images/header/b2022-logo.svg" />
<Title>Medalhas Olimpiadas de Inverno 2022</Title>
</Content>
<Back src="https://olympics.com/images/static/beijing-images/header/b2022-mountains-right-v2.svg" />
</Wrapper>
)
}
export default HeaderCriar o arquivo src/components/Footer/styles.js
import styled from "styled-components"
export const Wrapper = styled.footer`
height: 8rem;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
background: linear-gradient(90deg, #e8edf5 0, #fff 100%);
`
export const Credits = styled.h1`
text-align: center;
color: #444;
& a {
color: #1c50a1 !important;
&:hover {
text-decoration: underline;
}
}
`Alterar o arquivo src/components/Footer/index.jsx
import React from "react"
import { Wrapper, Credits } from "./styles"
const Footer = () => {
return (
<Wrapper>
<Credits>
Desenvolvido com amor por{" "}
<a href="https://johnywalves.com.br/">Johny W. Alves</a>
</Credits>
</Wrapper>
)
}
export default FooterCriar o arquivo src/components/Main/styles.js
import styled from "styled-components"
export const Wrapper = styled.main`
min-height: calc(100vh - 16rem);
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
`Alterar o arquivo src/components/Main/index.jsx
import React from "react"
import { Wrapper } from "./styles"
const Main = ({ children }) => {
return <Wrapper>{children}</Wrapper>
}
export default MainCom o comando yarn start podemos visualizar a resposta pelo localhost:3000
Listagem de informações (Medalhas)
Renomear o src/routes/Medals.jsx para src/routes/Medals/index.jsx
import React from "react"
import Header from "./Header"
import Row from "./Row"
import { Wrapper } from "./styles"
const teams = [
{
team: "norway",
description: "Norway",
gold: 14,
silver: 7,
bronze: 8,
},
{
team: "germany",
description: "Germany",
gold: 10,
silver: 7,
bronze: 5,
},
{
team: "united-states-of-america",
description: "United States of America",
gold: 8,
silver: 8,
bronze: 5,
},
{
team: "sweden",
description: "Sweden",
gold: 7,
silver: 4,
bronze: 4,
},
{
team: "china",
description: "People`s Republic of China",
gold: 7,
silver: 4,
bronze: 2,
},
]
const Medals = () => {
return (
<Wrapper>
<Header />
{teams.map((team) => (
<Row key={team.team} {...team} />
))}
</Wrapper>
)
}
export default MedalsCriar o arquivo src/routes/Medal/styles.js
import styled from "styled-components"
export const Wrapper = styled.div`
min-height: calc(100vh - 16rem);
width: 100%;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
`Com o comando yarn start podemos visualizar a resposta pelo localhost:3000
Cabeçalho do quadro de medalhas
Criar o arquivo src/routes/Medal/Header/index.jsx
import React from "react"
import { Wrapper, Team, Medals, Gold, Silver, Bronze, Total } from "./styles"
const MedalsHeader = () => {
return (
<Wrapper>
<Team>Time</Team>
<Medals>
<Gold />
<Silver />
<Bronze />
<Total />
</Medals>
</Wrapper>
)
}
export default MedalsHeaderCriar o arquivo src/routes/Medal/Header/styles.js
import styled from "styled-components"
export const Wrapper = styled.div`
font-size: 2rem;
font-weight: bold;
display: flex;
flex-direction: row;
color: #fff;
background-color: #444;
height: 5rem;
width: 100%;
margin: 0 0 0.5rem;
padding: 0 calc((100% - 88rem) / 2);
`
export const Team = styled.p`
display: flex;
align-items: center;
height: 5rem;
width: 50rem;
margin-left: 18rem;
`
export const Medals = styled.div`
display: flex;
flex-direction: row;
`
export const Gold = styled.div`
background-color: #fcc861;
border-radius: 50%;
height: 3rem;
width: 3rem;
margin: 1rem;
`
export const Silver = styled.div`
background-color: #e5e5e5;
border-radius: 50%;
height: 3rem;
width: 3rem;
margin: 1rem;
`
export const Bronze = styled.div`
background-color: #dcb386;
border-radius: 50%;
height: 3rem;
width: 3rem;
margin: 1rem;
`
export const Total = styled.div`
background-color: #fff;
border-radius: 50%;
height: 3rem;
width: 3rem;
margin: 1rem;
`Com o comando yarn start podemos visualizar a resposta pelo localhost:3000
Itens do quadro de medalhas
Criar o arquivo src/routes/Medal/Row/index.jsx
import React from "react"
import { Link } from "react-router-dom"
import { Wrapper, Flag, Description, Medal } from "./styles"
const MedalsRow = ({ team, description, gold, silver, bronze }) => {
return (
<Wrapper>
<Flag team={team} />
<Description>
<Link to={"/" + team}>{description}</Link>
</Description>
<Medal>{gold}</Medal>
<Medal>{silver}</Medal>
<Medal>{bronze}</Medal>
<Medal>{gold + silver + bronze}</Medal>
</Wrapper>
)
}
export default MedalsRowCriar o arquivo src/routes/Medal/Row/styles.js
import styled from "styled-components"
export const Wrapper = styled.div`
height: 5rem;
font-size: 2rem;
display: flex;
flex-direction: row;
margin: 0.5rem 0;
`
export const Flag = styled.div`
background-image: url(${({ team }) =>
"https://www.countryflags.com/wp-content/uploads/" +
team +
"-flag-png-large.png"});
background-position: center;
background-size: contain;
background-repeat: no-repeat;
height: 5rem;
width: 18rem;
`
export const Description = styled.p`
display: flex;
align-items: center;
text-align: left;
height: 5rem;
width: 50rem;
&:hover {
text-decoration: underline;
}
`
export const Medal = styled.p`
display: flex;
justify-content: center;
align-items: center;
height: 5rem;
width: 5rem;
`Com o comando yarn start podemos visualizar a resposta pelo localhost:3000
Links no Cabeçalho da página
Criar o arquivo src/components/Header/index.js
import React from "react"
import { Link } from "react-router-dom"
import { Wrapper, Content, Logo, Title, Back } from "./styles"
const Header = () => {
return (
<Link to="/">
<Wrapper>
<Content>
<Logo src="https://olympics.com/en/images/static/beijing-images/header/b2022-logo.svg" />
<Title>Medalhas Olimpíadas de Inverno 2022</Title>
</Content>
<Back src="https://olympics.com/images/static/beijing-images/header/b2022-mountains-right-v2.svg" />
</Wrapper>
</Link>
)
}
export default HeaderCom o comando yarn start podemos visualizar a resposta pelo localhost:3000
Listagem de informações (Times)
Vamos listar o detalhe dos países de acordo com o caminho informado
Renomear o src/routes/Teams.jsx para src/routes/Teams/index.jsx e mudar o conteúdo para adicionar a lista de países, ler a rota e apresentar as informações pela instrução
import React, { useMemo } from "react"
import { useParams } from "react-router-dom"
import { Wrapper, Flag, Name, Description } from "./styles"
const teams = [
{
id: "norway",
name: "Norway",
description:
"The Norwegian flag is a white-fimbriated blue Nordic cross on a red field. The used colors in the flag are blue, red, white. The proportion of the Norwegian flag is 8:11. The Flag of Norway was adopted in 1821. The first use of the current flag design was in 1821. The last change to the current Norwegian flag design was in 1899.",
},
{
id: "germany",
name: "Germany",
description:
"The German flag is a horizontal triband. The used colors in the flag are red, yellow, black. The proportion of the German flag is 3:5. The Flag of Germany was adopted in 1918. The first use of the current flag design was in 1848. The last change to the current German flag design was in 1949.",
},
{
id: "united-states-of-america",
name: "United States of America",
description:
"The United States flag – USA flag – American flag is a flag with thirteen horizontal stripes with 50 white stars in a blue field. The used colors in the flag are blue, red, white. The proportion of the United States flag – USA flag – American flag is 10:19. The Flag of the United States was adopted in 1960. The first use of the current flag design was in 1818. The last change to the current United States flag design was in 1960.",
},
{
id: "sweden",
name: "Sweden",
description:
"The Swedish flag is a one coloured field with a cross. The used colors in the flag are blue, yellow. The proportion of the Swedish flag is 5:8. The Flag of Sweden was adopted in 1906. The first use of the current flag design was in 1562. The last change to the current Swedish flag design was in 1906.",
},
{
id: "china",
name: "People`s Republic of China",
description:
"The Chinese flag is a solid flag with four small stars and one bigger star in the upper left corner. The used colors in the flag are red, yellow. The proportion of the Chinese flag is 2:3. The Flag of China was adopted in 1949. The first use of the current flag design was in 1949.",
},
]
const Teams = () => {
const { team } = useParams()
const { id, name, description } = useMemo(() => {
const current = teams.find(({ id: id_team }) => id_team === team)
if (current) {
return current
}
return { id: "", name: "", description: "" }
}, [team])
return (
<Wrapper>
<Name>{name}</Name>
<Flag id={id} />
<Description>{description}</Description>
</Wrapper>
)
}
export default TeamsCriar o arquivo com estilo src/routes/Teams/styles.js
import styled from "styled-components"
export const Wrapper = styled.div`
display: flex;
flex-direction: column;
align-items: center;
width: 88rem;
padding-top: 2rem;
`
export const Name = styled.h1`
font-size: 3rem;
margin: 1rem 0;
`
export const Flag = styled.div`
background-image: url(${({ id }) =>
"https://www.countryflags.com/wp-content/uploads/" +
id +
"-flag-png-large.png"});
background-position: center;
background-size: contain;
background-repeat: no-repeat;
height: 18rem;
width: 30rem;
margin: 1rem 0;
`
export const Description = styled.p`
font-size: 2rem;
margin: 2rem 0 0;
`Com o comando yarn start podemos visualizar a resposta pelo localhost:3000
API
- Explicação da biblioteca
json-server; - Explicação da biblioteca
concurrently;
yarn add json-server concurrently
# or
npm i json-server concurrentlyAdicionar no package.json em scripts
// ...
"scripts": {
// ...
"server": "npx json-server --watch db.json --port 8000",
"dev": "concurrently \"yarn start\" \"yarn server\""
}
// ...Criar o arquivo db.json na raiz, que irá servir como nosso banco de dados inicial
{
"medals": [
{
"team": "norway",
"description": "Norway",
"gold": 14,
"silver": 7,
"bronze": 8
},
{
"team": "germany",
"description": "Germany",
"gold": 10,
"silver": 7,
"bronze": 5
},
{
"team": "united-states-of-america",
"description": "United States of America",
"gold": 8,
"silver": 8,
"bronze": 5
},
{
"team": "sweden",
"description": "Sweden",
"gold": 7,
"silver": 4,
"bronze": 4
},
{
"team": "china",
"description": "People`s Republic of China",
"gold": 7,
"silver": 4,
"bronze": 2
}
],
"teams": [
{
"id": "norway",
"name": "Norway",
"description": "The Norwegian flag is a white-fimbriated blue Nordic cross on a red field. The used colors in the flag are blue, red, white. The proportion of the Norwegian flag is 8:11. The Flag of Norway was adopted in 1821. The first use of the current flag design was in 1821. The last change to the current Norwegian flag design was in 1899."
},
{
"id": "germany",
"name": "Germany",
"description": "The German flag is a horizontal triband. The used colors in the flag are red, yellow, black. The proportion of the German flag is 3:5. The Flag of Germany was adopted in 1918. The first use of the current flag design was in 1848. The last change to the current German flag design was in 1949."
},
{
"id": "united-states-of-america",
"name": "United States of America",
"description": "The United States flag – USA flag – American flag is a flag with thirteen horizontal stripes with 50 white stars in a blue field. The used colors in the flag are blue, red, white. The proportion of the United States flag – USA flag – American flag is 10:19. The Flag of the United States was adopted in 1960. The first use of the current flag design was in 1818. The last change to the current United States flag design was in 1960."
},
{
"id": "sweden",
"name": "Sweden",
"description": "The Swedish flag is a one coloured field with a cross. The used colors in the flag are blue, yellow. The proportion of the Swedish flag is 5:8. The Flag of Sweden was adopted in 1906. The first use of the current flag design was in 1562. The last change to the current Swedish flag design was in 1906."
},
{
"id": "china",
"name": "People`s Republic of China",
"description": "The Chinese flag is a solid flag with four small stars and one bigger star in the upper left corner. The used colors in the flag are red, yellow. The proportion of the Chinese flag is 2:3. The Flag of China was adopted in 1949. The first use of the current flag design was in 1949."
}
]
}Alterar o src/routes/Medals/index.jsx, para fazer a chamada na API e gerenciar os estados com a resposta
import React, { useState, useEffect } from "react"
import Header from "./Header"
import Row from "./Row"
import { Wrapper } from "./styles"
const Medals = () => {
const [medals, setMedals] = useState([])
useEffect(() => {
fetch("http://localhost:8000/medals")
.then((response) => response.json())
.then((data) => setMedals(data))
}, [])
return (
<Wrapper>
<Header />
{medals.map((team) => (
<Row key={team.team} {...team} />
))}
</Wrapper>
)
}
export default MedalsAlterar o routes/Teams/index.jsx, para fazer a chamada na API e gerenciar os estados com a resposta
import React, { useState, useEffect } from "react"
import { useParams } from "react-router-dom"
import { Wrapper, Flag, Name, Description } from "./styles"
const Teams = () => {
const { team } = useParams()
const [current, setCurrent] = useState()
useEffect(() => {
fetch(`http://localhost:8000/teams?id=${team}`)
.then((response) => response.json())
.then((data) => data && data.length > 0 && setCurrent(data[0]))
}, [team])
if (!current) {
return (
<Wrapper>
<Name>Time não encontrado</Name>
</Wrapper>
)
}
return (
<Wrapper>
<Name>{current.name}</Name>
<Flag id={current.id} />
<Description>{current.description}</Description>
</Wrapper>
)
}
export default TeamsCom o comando yarn dev podemos visualizar a resposta pelo localhost:3000


