Tópicos Especiais

Chrysthian Simão

Introdução a Frameworks de Frontend

Tópicos Especiais

Desenvolvimento de projetos web

 

  • Backend com C# e .Net Core
     
  • Frontend com React e TS

Cliente x Servidor

Cliente

(estamos aqui)

Servidor

Model-View-Controller

Alguns exemplos legais

Web Básico

HTML Básico

É uma linguagem de marcação para apresentar conteúdo separado por <tags>.

 

Essas tags são simples e existem desde o início da internet, encapsuladas em arquivos com a extensão .html

HTML Básico

Esse é um dos tipos de arquivo que trafegam pelo protocolo HTTP que é utilizado para montar a nossa página web.

 

Essas tags são organizadas numa estrutura de árvore chamada DOM (Document Object Model).

Entendendo a árvore do DOM

<html>
    <head>
        <title>My Title</title>
    </head>
    <body>
        <h1>My Header</h1>
        <a href="wwww.google.com">My Link</a>
    </body>
</html>

(esse arquivo está no repositório na pasta WebBasico)

Entendendo a árvore do DOM

Entendendo a árvore do DOM

CSS Básico

Dar uma cara melhor para as coisas começou a fazer diferença, então entrou o CSS - Cascade Styling Sheets.

 

São marcações que alteram a aparências das páginas de acordo com critérios chamados "selectors".

CSS Básico

Os selectors... selecionam os elementos das páginas que soincidem com os critérios definidos e aplicam as alterações necessárias.

CSS Básico

As principais funções além de estilização são:

  • Usabilidade (como leitores de tela para deficientes visuais)
     
  • Responsividade (múltiplos tamanhos de tela) são coisas resolvidas com o CSS.

Em resumo mudam isso

Pra isso

(esse arquivo está no repositório na pasta WebBasico/Nebula)

JS Básico

Não só de aparências, mas sentiu-se a necessidade de trazer funcionalidades as páginas web.

 

Então em meados de 1993 a Netscape fez a primeira versão da linguagem e lançou em 1994 no seu navegador.

JS Básico

Javascript é uma linguagem não tipada o que permite algumas... liberdades poéticas com tipagem e lógica de código num geral.

E como junta tudo?

<link rel="stylesheet" href="styles.css">
<script src="script.js"></script>

(esse arquivo está no repositório na pasta WebBasico/Template)

CSS

Javascript

Tags HTML, que incorporam a árvore do DOM

Particularidades do JS

Boolean

let y = true; 
let x = false;
let z = null;

z = 3 > 2;    // true
// resultados assumindo uma chamada 
// a função teste(z) aqui do lado -->

z = y && x;      //false
z = undefined;   //false
z = null;        //false
z = "";          //false
z = "bolovo";    //true
z = 0;           //false
z = NaN;         //false
z = 10;          //true
z = {};          //true
z = [];          //true
function teste( z ){
    if( z ){
        alert("true");
    } else {
        alert("false");
    }
};

Nada muito novo ali em cima, mas igualdade é uma coisa mais delicada!

String

let a = "Laranja";
let b = "Batata";

console.log(a > b); // true

console.log(a.localeCompare(b)); // -1

console.log(b.localeCompare(a)); // 1

console.log(a.localeCompare(a)); // 0

Array

let a = new Array();  //usamos um construtor para criar um array
let a = [];           //também é um construtor válido

let cars = new Array("Fusca", "Palio", "BMW");
let cars = ["Fusca", "Palio", "BMW"];

let name = cars[0];     //'Fusca'

let x = cars.length;    // obtem o número de elementos (3)
let y = cars.sort();    // ordenação nativa

let fruits = ["Banana", "Laranja", "Maçã", "Manga"];
fruits.push("Limão");                  // adiciona um elemento ao array
fruits[fruits.length] = "Abacate";     // Também funciona

Array

let wtf = [];

wtf["a"] = "abacate";

wtf[0];     // undefined
wtf["a"];   // 'abacate'

function mensagem( str ){ 
    alert( str ); 
}

wtf["funcao"] = mensagem;
wtf["funcao"]("bolinho"); // que diabos!?

Ponteiros

Javascript usa ponteiros (ou referências de memória, como preferir). É um conceito importante para escrever um código otimizado.

 

Os ponteiros do Javascript funcionam da mesma forma que em Java com contagem de referência.

Ponteiros

Assim como no Java, no JS tudo são ponteiros, a própria declaração de uma variável acontece da seguinte forma:

  let a = [];
  • O código é interpretado por uma linguagem de baixo nível
  • Memória é alocada para guardar a informação
  • A variável recebe o ponteiro de memória contendo a informação

Ponteiros

let a = 2; 
let b = a;

// Só há um espaço reservado em memória com o nosso objeto
// No entanto há duas referências ("a" e "b") para o mesmo
// endereço de memória

b = null;

// Isto faz com que a referência ao objeto da variável "b" 
// deixe de existir mantendo apenas uma referência em "a"

a = null;

// Agora sem as duas referências o valor alocado em memória 
// pode ser sinalizado para garbage collection

Ponteiros

Algumas coisas começam a fazer sentido agora como por exemplo, porque consideram o operador "new" computacionalmente caro, é porque ele aloca fisicamente memória.

 

Isso não é só sobre JS mas linguagens num geral.

 

Se a linguagem usa uma VM inteligente, ela gerencia a própria memória e consegue amenizar o impacto em tempo de execução.

Null e Undefined

Null e Undefined são coisas diferentes para a linguagem, mas são logicamente iguais (então por isso é comum confundir).

 

Uma variável declarada vazia, sem atribuição é undefined, porque nenhuma memória foi alocada para ela ainda.

 

Se a variável recebe a atribução de null, significa que ela continha algo e está pronta para ser coletada no Garbage Collector porque ela não será mais usada.

Afetando a página com JS

Objeto Math

Math.sqrt(16);   //4
Math.PI;         //3.141592653589793
Math.cos(1);     //0.5403023058681398
Math.ceil(1.2);  //2
Math.floor(1.2); //1
Math.random();   //Um número aleatório entre 0 e 1

//esta função retorna um valor aleatório entre um mínimo e um máximo
function getRandom(min, max) {
  return Math.floor(Math.random() * (max - min)) + min;
}

Objeto document

<html>
    <head>
        <title>My Title</title>
    </head>

    <body>
        <h1 id="header">My header</h1>
        <a href="http://www.google.com.br" id="myLink">My link</a>
    </body>
</html>

<script>
    console.log( document.getElementById("myLink") );
</script>

Objeto document

//Retorna uma lista de elementos com o nome de tag HTML fornecido.
document.getElementsByTagName();

function encontrarTagP() {
  const all = document.getElementsByTagName('p');
  let num = all.length;
  alert('Existem ' + num + ' parágrafos neste documento');
}

Objeto document

//Retorna uma lista de elementos com o nome de classe CSS fornecido.
document.getElementsByClassName();

<p class="test">hello</p>
            
<script>
   let test = document.getElementsByClassName("test");
   console.log(test);
</script>

Interagindo com Tags

Tags HTML podem ser manipuladas normalmente com JS, é o uso mais comum da linguagem.

 

Atributos, valores e eventos podem ser manipulados programaticamente

Interagindo com Tags

<html>
    <head>
        <title>My Title</title>
    </head>

    <body>
        <h1 id="header">My header</h1>
        <a href="http://www.google.com.br" id="myLink">My link</a>
    </body>
</html>

<script>
    console.log( document.getElementById("myLink").href );
</script>

Eventos do Navegador

<html>
    <head>
        <title>My Title</title>
    </head>

    <body>
        <h1 id="header">My header</h1>
        <a href="http://www.google.com.br" id="myLink">My link</a><br>
        <input type="button" value="Click me!"
         onclick="exibirConsole()">
    </body>
</html>

<script>
    function exibirConsole(){
        console.log( document.getElementById("myLink").href );
    }
</script>

Manipulando HTML

<html>
<body>

<h1 id="header">Você não clicou no botão</h1>

<input type="button" value="Clique em mim!" onclick="change()">
<script>

let count = 0;

function change(){
    let element = document.getElementById("header");
    count++;
    element.innerHTML = "Você clicou no botão " + count + " vez(es)!";

    console.log(window.count);
}

</script>
</body>
</html> 

Let's get Ready to Rumble!

Adivinhe a cor

React!

Um pouco de história

Era uma vez o facebook... Eles tem uma aplicação de complexidade crescente que precisava de um controle adequado na exibição, sem que as coisas fossem complexas demais para gerenciar.

A partir daí os engenheiros criaram essa biblioteca, viram que ela era muito robusta, então disponibilizaram ela em código aberto para a comunidade.

Dezoito versões depois, cá estamos.

Framework

Um framework é um conjunto de ferramentas e bibliotecas que fornecem um conjunto de recursos e funcionalidades prontas para programadores.

 

Isso permite construir aplicativos mais rapidamente, com menos esforço e código, e com menores chances de erros.

Framework

Algumas pessoas dizem que o React não é um framework e sim uma biblioteca, porque o react te da ferramentas, mas você é livre pra usá-las como achar melhor.

É bom porque você pode fazer o que quiser

É ruim porque você pode fazer o que quiser!

Porque React?

Aplicações web ricas que precisam ser atualizadas em tempo real e que permita a criação de soluções escaláveis em times de qualquer tamanho.

Componentes

A principal característica do React é permitir a criação de componentes reutilizáveis, como blocos de montar.

 

Estes componentes podem ser tão atômicos quanto necessário, de linhas e botões, até a páginas inteiras.

Virtual DOM

O que torna o React tão rãpido é o conceito introduzido pela lib, o Virtual DOM.

 

A árvore do DOM como vimos até agora é lenta demais para atualizações constantes.

Virtual DOM

Como o nome diz, é uma representação da árvore do DOM em memória, que uma vez atualizada é replicada inteira para o DOM final, sendo muito mais rápida porque acaba modificando somente o elemento necessário e não reconstruindo todos os nós.

Montando Ambiente

Node.js

É um motor de tempo de execução JavaScript de código aberto. Ele executa o código JavaScript fora de um navegador.

Node.js

Como eu sei que instalou corretamente?

node --version
npm --version
npx --version

NPM

O NPM (Node Package Manager), é o gerenciador de pacotes do node, e permite baixar e gerenciar bibliotecas javascript.

 

React é uma delas, mas muitas outras bibliotecas podem ser instaladas através dessa ferramenta.

node_modules

Hands On

Hello React.js + TS

npx create-react-app my-app --template typescript
npm start

Hands On

localhost:3000

JSX (WTF!?)

function MyButton() {
  return (
    <button>I'm a button</button>
  );
}
export default function MyApp() {
  return (
    <div>
      <h1>Welcome to my app</h1>
      <MyButton />
    </div>
  );
}

JSX / TSX

JSX é uma extensão da linguagem JavaScript que é usada pelo React para criar interfaces de usuário.

 

Ele permite que você misture código JS com sintaxe de HTML, o que torna mais fácil escrever componentes de interface de usuário em um único arquivo de código.

 

Diferente do Angular, que traz lógica para o HTML, o React traz o HTML pra dentro do JS.

 

A variante do JSX para Typescript (que vamos usar) é TSX.

SPA

Single-page application é uma aplicação que carrega uma única página web, e então atualiza o conteúdo desse documento utilizando Javascript.

SPA

Da mesma forma que demonstramos que é possível trazer interação no exemplo de adivinhar a cor, React e outras bibliotecas e frameworks elevam isso trazendo estruturas mais complexas e otimizadas

Rotas

Então como navegamos pela aplicação se quisermos mais do que... uma página?

 

Usamos o conceito de rotas, o JS toma controle do histórico de navegador para simular o comportamento, e dar a impressão de múltiplas páginas, mas no fim do dia é uma só, atualizada constantemente

Rotas

Como estamos usando o React vanilla, temos que usar uma biblioteca externa para incluir e configurar rotas, alguns frameworks como o Next.js já tem configuradas as rotas no template padrão

Rotas

npm install --save react-router-dom

Adicionamos bibliotecas ao projeto para não ser necessário fazer muitas coisas no braço, assim como C# tem o nuGet, o Java tem o Maven, o Node tem o NPM, e instalamos as bibliotecas por comandos node

Simple component

import React from 'react';

export default function Simple() {
  return (<div> Simples </div>)
}

Simple component+

import React, { ReactElement } from 'react';

interface params {
  name: string;
  age?: number;
}

const SimpleWithParam = (values: params): ReactElement => {
  return (<div> {values.name} </div>)
}

export default SimpleWithParam;

Simple component++ (v2)

import React from 'react';

interface params {
  children: React.ReactNode
}

const SimpleWithChildren = (values: params)
: React.ReactElement => {
  return (<div> {values.children} </div>)
}


export default SimpleWithChildren;

Como usa?

import Simple from './components/Simple'
import SimpleWithChildren from './components/SimpleWithChildren'
import SimpleWithParam from './components/SimpleWithParam'

export default function Home() {
  return (
    <div>
      <Simple />

  	  <SimpleWithChildren>
        <h1>Quero café</h1>
      </SimpleWithChildren>

      <SimpleWithParam name="Takoyaki" />
    </div>
  )
}

CSS + React

React é uma biblioteca que interpreta as páginas JSX/TSX transfere elas para o Virtual DOM, e este, atualiza o DOM do navegador.

 

Isso significa que o navegador não entende a sintaxe de um componente ou página React

CSS + React

Então algumas coisas precisam ser ligeiramente adaptadas, no caso do CSS, normalmente utilizamos o atributo class para aplicar um estilo CSS, mas essa é uma palavra reservada, então em TSX usamos className

Responsividade

Existem ferramentas para ajudar na responsividade (conteúdo adequado ao tamanho de tela), uma delas é utilizar media queries do CSS, isso permite que regras CSS sejam aplicadas conforme o tamanho da tela do navegador

Responsividade

@media (min-width: 640px) {
 /*
 	aqui só será aplicado se a tela
 	tiver 640px ou MAIS
 */
}


@media (min-width:400px) and (max-width:900px) {
	/* Não menor que 400px nem maior que 900px */
}

Responsividade

Outra ferramenta é usar elementos com
display:flex
display:grid

1-line-css layouts

React hooks

React tem a sua forma de reagir a coisas que ocorrem na página, incluímos em nossos componentes algumas coisas específicas da biblioteca, chamados hooks

React hooks

Por padrão, hooks são nomeados com o prefixo "use", como useState, useEffect, useMemo, useRouter etc...

useState

useState é um comportamento adicionado aos nosso componentes que guarda... um estado próprio do componente, algo que só ele precisa saber.

useState

const [count, setCount] = useState(0)

Variável que guarda o valor

função pra alterar esse valor

chamada do hook + inicialização

useEffect

Essa é a forma de reagir a aplicação, mudança do ciclo de vida do nosso componente (criação, montagem e desmontagem de acordo com o virtualDOM).

 

É uma função que vai ser chamada e fazer... alguma coisa quando um critério de execução acontecer

useEffect

useEffect(
    () => {
        // executa o side effect / função
    },
    // array opcional de critérios para execução
    [
        // 0 ou mais critérios
    ] 
)

useEffect

useEffect(() => {
  // Executa toda vez que o componente for
  // renderizado (mudou valor, 
  // desenhou um componente filho etc...)
});

useEffect(() => {
  // Executa apenas uma vez
  // quando o componente aprece
}, []);

useEffect(() => {
  // Executa a primeira vez que renderizar
  // E toda vez que "count" mudar de valor
}, [count, count2]);

useEffect

No fim só parece aplicar lógica com passos extras! (meme aqui)
 

Mas agora coloque em perpectiva que chamadas de APIs externas podem acontecer no useEffect

 

(Ex. apertei um botão para envio de um formulário, eu vou REAGIR a resposta)

Gerenciando estados da aplicação

Lembra da história do facebook com React?

Eles precisavam controlar não só o estado de cada componente, mas o estado da aplicação como um todo, para que cada componente reaja de acordo com as mudanças da aplicação.

 

Ex. Usuário logado, ele tem permissões a quais telas? qual o tema de cores ele escolheu, claro ou escuro?

Gerenciando estados da aplicação

Além do que, não era incomum componentes precisarem mandar informações para outros componentes, e aí, comofas?

 

Entrou em pauta o gerenciamento de estados da aplicação, pra não virar um macarrão de componetnes pasasndo informações de forma desorganizada, isso começou com uma tecnologia chamada Redux.

 

MAS para a sua sorte esse tipo de abordagem evoluiu pra alguns conceitos com uma curva de aprendizado mais amena.

Gerenciando estados da aplicação

Store

É basicamente uma forma de armazenamento de variáveis e funções globais, que afeta a aplicação como um todo.

 

Uma alteração faz uma cascata de chamadas para quem está observando, é um design pattern chamado de observer

Zustand

npm install zustand

Store

Primeiro precisamos criar essa store

import { create } from "zustand"

// definição do meu estado global
interface DarkModeStore {
  dark: boolean // variável
  setDark: () => void // método pra alterar minha variável
}

//crio um estado baseado na minha interface
export const useDarkMode = create<DarkModeStore>()(
  // inicializo as minhas variáveis e defino os comportamentos
  (set) => ({
    dark: true,
    setDark: () => set((store) => ({ dark: !store.dark })),
  })
)

Store

Então acessamos ela de dentro dos componetentes

import { useDarkMode } from "../../store/darkModeStore"

const Window = (): ReactElement => {
  const isDark = useDarkMode((state) => {
    return state.dark
  })
  
  const backgorundColor = isDark ? "#0e4a66" : "#0e4aaa"

  return (
    <div className="window" style={{
    	background: backgorundColor,
    }}>
    </div>)
}

Hands on!

Crie um projeto em React (pode usar meus templates) que tenha um componente que apresente um contador e um botão.

Quando eu no botão uma vez ele incrementa o valor em um.

Utilize o hook de useState

Hands on!

Agora crie um novo componente que faça o mesmo MAS usando uma store do zustand.

Coloque múltiplos componentes iguais na tela pra mostrar o estado global.

Integrando front e backend

C#

Mais algumas configurações para o nosso backend para habilitar comunicação com o frontend, no projeto C#, há um arquivo de configuração chamado launchSettings.json.


Através dele vamos configurar uma porta padrão para que a nossa aplicação rode.

 

Dentro desse arquivo mude as portas dos endereços listados para a porta que você deseja (por exemplo 4000)

CORS

Cross-Origin Resource Sharing, a sina dos frontends, o terror dos dev ops.

// nome arbitrário
var origins = "_origins";

builder.Services.AddCors(options =>
{
	options.AddPolicy(name: origins,
	policy =>
		{
			policy.WithOrigins("http://localhost:3000")
				.AllowAnyHeader()
				.AllowAnyMethod();
		});
});

WebApplication app = builder.Build();
app.UseCors(origins);

Lá no frontend

  useEffect(() => {
    fetch('http://localhost:4000/api/icecream/getAll',
    {method: "GET"})
      .then((res) => res.json())
      .then((data) => {
        console.log(data);
      })
  }, [])

Dentro do seu componente (por exemplo)

Lá no frontend

  useEffect(() => {
    if (!isDark) {
      const data = {
        id: "a2dcc71f-7705-4db6-8cf4-4f87994203b1",
        name: "Framboesa",
      }

      fetch("http://localhost:4000/api/flavors", {
        method: "PUT",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify(data),
      })
        .then((res) => res.json())
        .then((data) => {
          console.log(data)
        })
    }
  }, [isDark])

Referências Legais

Avaliação A1!

  • Frontend em react e TS, backend em C# com Asp.net
  • Pelo menos 3 componentes com lógica
  • Frontend responsivo (tem que caber de desktop a 375px)
  • Utilizar Rest API com pelo menos 7 endpoints
  • GET, POST, PATCH, PUT, DELETE
  • Persistência no banco
  • O tema que você quiser, defendendo o código durante a apresentação

Tópicos Especiais 4

By Chrysthian Simão

Tópicos Especiais 4

  • 209