Buscar

anotacoes_bootcampIGTI_frontEnd

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 148 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 148 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 9, do total de 148 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

Estas anotações são sobre o bootcamp Desenvolvedor Front-End da instituição IGTI iniciado em 20/11/2020.
https://online.igti.com.br/courses
Sumário
MÓDULO 01	4
Aula 01 - Introdução	5
Aula 02 - Node.js	6
Aula 03 – Noções HTML	8
Aula 04 – Noções CSS	9
Aula 05 - Introdução ao JavaScript	10
Aula 06 - JavaScript - comandos de bloco	11
Aula 07 - JavaScript - manipulação do DOM	15
Aula 08 - JavaScript - formulários e manipulação de eventos	18
Aula 09 - CRUD com HTML, CSS e JavaScript	23
Aula 10 - JavaScript moderno – Introdução	36
Aula 11 - JavaScript moderno - Manipulação de arrays	39
Aula 12 - JavaScript moderno - Rest/Spread operator e destructuring	44
Aula 13 - Refatoração do projeto de CRUD	46
Aula 14 - Introdução à programação assíncrona com JavaScript	47
Aula 15 - Funções setTimeout e setInterval	48
Aula 16 - Requisições HTTP com JavaScript	49
MÓDULO 02	52
Aula 01 – Apresentação do curso	53
Aula 02 – Conceitos e termos	54
Aula 03 - Instalação do Node.js - Visual Studio Code	55
Aula 04 - Primeira App React	56
Aula 05 - Conhecendo nossa App	57
Aula 06 - Calculadora	60
Aula 07 - Estilizando a nossa calculadora	66
Aula 08 - Dando funções à nossa Calculadora	74
Aula 09 - Axios	87
Aula 10 - Nossa APP	88
Aula 11 – Design da App	89
Aula 12 – Criando a App	90
Aula 13 - Criando a instância do Axios	91
Aula 14 - Aula teórica : Promisses	92
Aula 15 - Iniciando a nossa controller genérico	93
Aula 16 - Testando a nossa função de Schema	94
Aula 17 - Criando e testando a nossa função getByld	96
Aula 18 - Entendendo Generics	98
Aula 19 – GetAll	100
Aula 20 - Criando nosso GetByPartialName	105
Aula 21 – Aula teórica: Hooks	107
Aula 22 - Material UI	108
Aula 23 – TypeScript	109
Aula 24 - Apresentando o componente Detalhe	110
Aula 25 - Criando a estrutura genérica de dados	111
Aula 26 – Componente de detalhe	112
Aula 27 - Criando o hook useAsync	117
Aula 28 – Implementando o componente detalhe	119
Aula 29 - Componente lista	123
Aula 30 - Roteando nossa app	124
Aula 31 – Utilizando useHistory	125
Aula 32 – Terminando nossa App	126
Módulo 03	127
Aula 01 - Introdução e Preparação do Ambiente	128
Aula 02 - Arquitetura e Estrutura da Aplicação	129
Aula 03 - Componentes e Templates	130
Aula 04 - Desafio Guiado 1	135
Aula 05 – Diretivas Estruturais	141
Aula 06 - Comunicação Entre Componentes	147
Aula 07: Estilização de Componentes	156
MÓDULO 01
Aula 01 - Introdução
Aula 02 - Node.js
Para iniciar um projeto node.js é necessário criar um pacote do tipo .json, para isto, basta abrir o cmd, navegar até a pasta em que se deseja criar os pacotes e então digitar o seguinte:
npm init -y
E estará criado o projeto node.js em formato .json.
Existem dois tipos de dependências:
· Dependency: o tipo de dependência padrão local;
· Dev-dependency: o tipo de dependência que é utilizado pelo desenvolvedor apenas para o desenvolvimento, ou seja, isso não será utilizado no deploy quando a aplicação for para o servidor de fato;
Para criar uma dev-dependency para desenvolver com node.js, basta navegar pelo terminal até a pasta desejada e digitar:
npm install live-server –-save-dev
Então este comando irá inserir no package.json uma área responsável pelo controle de dependências de desenvolvimento (devDependencies); e também irá criar um arquivo, que não deve ser modificado, chamado package-lock.json que é responsável pelo controle de versões destas dependências.
Isto é de extrema utilidade pois cria um arquivo .json que grava quais dependências o projeto tem e caso seja necessário trocar de máquina o projeto, movendo apenas estes arquivos e executando o comando ‘npm install’ o npm instalará todas as dependências necessárias.
Para rodar o live-server, primeiro deve-se configurar que ele será responsável por rodar a aplicação e para isto, deve-se adicionar a key “start” no package.json com o valor “live-server”, ficando assim:
{
  "name": "aula-02-node-js",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "live-server"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "live-server": "^1.2.1"
  }
}
E então no terminal, na pasta em que o arquivo se encontra rodar:
npm start
Pronto, o navegador abrirá a aplicação.
Aula 03 – Noções HTML
Aula 04 – Noções CSS
Aula 05 - Introdução ao JavaScript
Aula 06 - JavaScript - comandos de bloco
Sintaxes:
// Comparando 2 números com if/else
var a = 3;
var b = 5;
if (a < b) {
  console.log(a + ' é menor que ' + b);
} else {
  if (a > b) {
    console.log(a + ' é maior que ' + b);
  } else {
    console.log(a + ' e ' + b + ' são iguais');
  }
}
// Validação de dia com if/else
var day = 1;
if (day === 1) {
  console.log('Domingo');
} else {
  if (day === 2) {
    console.log('Segunda-feira');
  } else {
    if (day === 3) {
      console.log('Terça-feira');
    } else {
      if (day === 4) {
        console.log('Quarta-feira');
      } else {
        if (day === 5) {
          console.log('Quinta-feira');
        } else {
          if (day === 6) {
            console.log('Sexta-feira');
          } else {
            if (day === 7) {
              console.log('Sábado');
            } else {
              console.log('Dia inválido');
            }
          }
        }
      }
    }
  }
}
// Validação de dia com switch
switch (day) {
  case 1:
    console.log('Domingo');
    break;
  case 2:
    console.log('Segunda-feira');
    break;
  case 3:
    console.log('Terça-feira');
    break;
  case 4:
    console.log('Quarta-feira');
    break;
  case 5:
    console.log('Quinta-feira');
    break;
  case 6:
    console.log('Sexta-feira');
    break;
  case 7:
    console.log('Sábado');
    break;
  default:
    console.log('Dia inválido');
}
// Comparando 2 números com operador ternário
var compareResult = a > b ? 1 : a < b ? -1 : 0;
// Verificando dia da semana com operador ternário
var weekDay =
  day === 1
    ? 'Domingo'
    : day === 2
    ? 'Segunda-feira'
    : day === 3
    ? 'Terça-feira'
    : day === 4
    ? 'Quarta-feira'
    : day === 5
    ? 'Quinta-feira'
    : day === 6
    ? 'Sexta-feira'
    : day === 7
    ? 'Sábado'
    : 'Dia inválido';
Aula 07 - JavaScript - manipulação do DOM
document.querySelector()
Para manipular elementos da página HTML via JS utiliza-se o método do objeto document ‘querySelector’, ele é responsável por selecionar um ou vários elementos da página HTML, estes podendo ser de três tipos:
var input1 = document.querySelector('#idGenerico');
input1.value = 'Raphael Gomide';
var input2 = document.querySelector('.classeGenerica');
input3.value = 'Abilonson';
var input3 = document.querySelector('elementoHTML'); //<p>, <h1>, etc...
input3.value = 'Jurema';
document.querySelectorAll();
Semelhante ao ‘querySelector()’ porém retorna uma nodeList com todos os elementor de um tipo especificado no argumento do método;
const important = document.querySelectorAll('urgent');
Uma maneira interessante de se manipular o conteúdo do texto de um elemento é após capturar o elemento desejado usando um querySelector, utiliza-se o método ‘.textContent();’ para alterar seu valor.
const important = document.querySelectorAll('urgent');
important.textContent = 'Olá Mundo! sou importante!';
Aqui é interessante mostrar que é possível manipular o CSS através do JS. Isto é feito através das classes em CSS.
Supões que se deseja alterar a formatação de um texto quando ele for clicado, para isto utilizamos a propriedade onclick no HTML que será responsável por executar esta função, e então criamos uma classe CSS com a propriedade desejada para então escrever uma função para adicionar essa classe à respectiva tag HTML.
Ficando com:
HTML:
<h1 id="toBeEmphasized" onclick="clicked(event)" class="">Olá Mundo!</h1>
CSS:
.emphasis {
  font-weight: bold;
  color: darkgreen;
}
JS:
function clicked() {
  const text = document.querySelector('#toBeEmphasized');
  classList = Array.from(text.classList);
  //Se tiver a classe emphasis a função irá remover estaclasse, caso contrário irá adicionar:
  if (classList.includes('emphasis')){
    text.classList.remove('emphasis');
    text.textContent = 'Sem o ".empahsis" nas classes deste objeto';
  } else {
    text.classList.add('emphasis');
    text.textContent = '".emphasis" foi adicionado';
  }
}
Este foi um exemplo de manipulação simples de CSS de um elemento HTML utilizando JS, demonstrando o método ‘remove()’ e ‘add()’ da classList do elemento HTML.
Aula 08 - JavaScript - formulários e manipulação de eventos
Para criar formulários em HTML utiliza-se a tag <form> e nele podem ser inseridos os campos que serão utilizados.
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Formulário</title>
  </head>
  <body>
    <form>
      <p>
        <textarea rows="10" cols="10">Conteúdo</textarea>
      </p>
      <p>
        <input type="text" id="input1" placeholder="Informe o seu nome" />
      </p>
      <p>
        <input type="email" id="input2" placeholder="Informe o seu email" />
      </p>
      <p>
        <input type="date" id="input3" placeholder="Informe o seu email" />
      </p>
      <p>
        <input type="checkbox" id="input4" placeholder="Informe o seu nome" />
        Rock
      </p>
      <p>
        <input
          type="radio"
          name="opcao"
          id="input2"
          placeholder="Informe o seu nome"
        />
        Sim
        <input
          type="radio"
          id="input2"
          name="opcao"
          placeholder="Informe o seu nome"
        />
        Não
      </p>
      <input type="submit" value="Enviar" />
    </form>
    <script src="./js/script.js"></script>
  </body>
</html>
Para manipular estes elementos com o JS basta fazer da mesma maneira como se manipularia qualquer outro elemento HTML, através do querySelector:
var input1 = document.querySelector('#input1');
input1.value = Bleblio;
Então o valor do imput1 será setado para ‘Bleblio’.
A função adEventListener() também desempenha um papel muito importante, é através dela que ao se executar uma ação na página o script em JS é executado.
function clicked() {
  const text = document.querySelector('#toBeEmphasized');
  classList = Array.from(text.classList);
  //Se tiver a classe emphasis a função irá remover esta classe, caso contrário irá adicionar:
  if (classList.includes('emphasis')){
    text.classList.remove('emphasis');
    text.textContent = 'Sem o ".empahsis" nas classes deste objeto';
  } else {
    text.classList.add('emphasis');
    text.textContent = '".emphasis" foi adicionado';
  }
};
function start() {
  let textInput = document.querySelector('#textInput');
  let form = document.querySelector('form');
  textInput.addEventListener('keyup', countTextLength);
  form.addEventListener('submit', preventSubmit);
}
function countTextLength(event) {
  let count = event.target.value.length;
  let span = document.querySelector('#textLength');
  span.textContent = count;
}
function preventSubmit(event) {
  event.preventDefault();
  alert('ainda não estamos funcionando, volte mais tarde!')
}
start();
Aula 09 - CRUD com HTML, CSS e JavaScript
Parte 01:
Nesta aula se aprende a manipular a inserção de elementos HTML através do JS. Isto é útil pois as vezes se deseja ciar uma lista ou coisa similar que sejam anexados elementos quando alguma acao é tomada; no exemplo quando um nome é digitado e apertado ENTER este é anexado a uma lista HTML.
A primeira coisa a se fazer é evitar que a página seja recarregada automaticamente ao dar o submit do form, para isto criamos uma função que é executada ao executarmos o submit do form que previne esta ação.
function start(){
  preventFormSubmit();
};
function preventFormSubmit(){
  function handleFormSubmit(event){
    event.preventDefault();
  }
  const form = document.querySelector('form');
  form.addEventListener('submit', handleFormSubmit);
}
start();
Nesta lógica, assim que o script for executado ele executará a função start() que será responsável por executar a preventFormSubmit(); 
Então com o adEventListener observando o form, sempre que for dado um ‘submit’ nele ele executará o handleFormSubmit, que recebe o ‘submit’ como argumento e roda o ‘submit’.preventDefault();
Parte 02:
Agora devemos pegar os dados inseridos no formulário, para anexa-los a uma lista de nome. Para isso é interessante ter uma função responsável por observar o formulário e assim que a tecla enter for pressionada pegar estes dados e salvar em um array para depois apresentá-los na tela.
Para ficar responsável por pegar estes dados criamos a função activateInput(), que observa e faz o push no array e o render() que renderiza esse array na tela
//variaveis globais
let inputName;
let globalNames = ['test'];
//funçoes gerais
function preventFormSubmit() {
  //prevent refresh da página
  function handleFormSubmit(event) {
    event.preventDefault();
  }
  const form = document.querySelector('form');
  form.addEventListener('submit', handleFormSubmit);
}
function activateInput() {
  //observa a tecla enter e quando pressionada adiciona ao globalNames o que for digitado no formulário
  function handleTyping(event) {
    if (event.key === 'Enter') {
      globalNames.push(event.target.value);
      render();
    }
  }
  inputName.focus();
  inputName.addEventListener('keyup', handleTyping);
}
function render() {
  //renderiza as informácoes do aray globalNames em forma de lista, através de push e appendChild
  let divNames = document.querySelector('#names');
  divNames.innerHTML = '';
  let ul = document.createElement('ul');
  for (let i = 0; i < globalNames.length; i++) {
    let currentName = globalNames[i];
    let li = document.createElement('li');
    li.textContent = currentName;
    ul.appendChild(li);
  }
  divNames.appendChild(ul);
}
//script a ser executado quando a página for carregada
function start() {
  //apelidos
  inputName = document.querySelector('#inputName');
  //açoes a serem executadas
  preventFormSubmit();
  activateInput();
  render();
}
start();
O principal aqui é como utiliza-se o createElement() e appendChild para criar e anexar os elementos HTML.
Parte 03:
Inicia-se fazendo alguma otimizações como limpar a tela ao renderizar uma nova lista.
Feito isto a deve-se criar a função de remoção de elemento a partir do botão, para isso utilizaremos o mesmo principio de createElement para a lista só que para o botão e para facilitar o entendimento do código, cria-se uma função para criar tal botão. Lembrando que após a remoção do item é necessário renderizar a lista novamente.
//variaveis globais
let inputName;
let globalNames = ['test'];
//funçoes gerais
function preventFormSubmit() {
  //prevent refresh da página
  function handleFormSubmit(event) {
    event.preventDefault();
  }
  const form = document.querySelector('form');
  form.addEventListener('submit', handleFormSubmit);
}
function activateInput() {
  //observa a tecla enter e quando pressionada adiciona ao globalNames o que for digitado no formulário
  function handleTyping(event) {
    if (event.key === 'Enter') {
      globalNames.push(event.target.value);
      render();
    }
    // if (event.key === 'ArrowUp') {
    //  console.log(globalNames);
    // }
  }
  inputName.focus();
  inputName.addEventListener('keyup', handleTyping);
}
function render() {
  function createDeleteButton(index) {
    function deleteName() {
      // console.log(globalNames[index])
      globalNames.splice(index, 1);
      render();
    }
    const button = document.createElement('button');
    button.textContent = 'x';
    button.classList.add('deleteButton');
    button.addEventListener('click', deleteName);
    return button;
  }
  //renderiza as informacoes do aray globalNames em forma de lista, através de push e appendChild
  let divNames = document.querySelector('#names');
  divNames.innerHTML = '';
  let ul = document.createElement('ul');
  for (let i = 0; i < globalNames.length; i++) {let currentName = globalNames[i];
    let li = document.createElement('li');
    let button = createDeleteButton(i);
    let span = document.createElement('span');
    span.textContent = currentName;
    li.appendChild(button);
    li.appendChild(span);
    ul.appendChild(li);
  }
  divNames.appendChild(ul);
  clearInput();
}
function clearInput() {
  inputName.value = '';
  inputName.focus();
}
//script a ser executado quando a página for carregada
function start() {
  //apelidos
  inputName = document.querySelector('#inputName');
  //açoes a serem executadas
  preventFormSubmit();
  activateInput();
  render();
}
start();
Parte 04:
Agora iremos mexer com a edição dos itens da lista. Para isto criamos uma função responsável por passar o valor do item para a barra de input e uma variável global para verificar se o item está sendo editado.
//variaveis globais
let inputName;
let currentIndex = null;
let globalNames = ['test','foo','spam'];
let isEditing = false;
//funçoes gerais
function preventFormSubmit() {
  //prevent refresh da página
  function handleFormSubmit(event) {
    event.preventDefault();
  }
  const form = document.querySelector('form');
  form.addEventListener('submit', handleFormSubmit);
}
function activateInput() {
  //observa a tecla enter e quando pressionada adiciona ao globalNames o que for digitado no formulário
  function updateName(newName){
    //responsável por fazer o update do item selecionado
    console.log(newName);
    console.log(currentIndex);
    globalNames[currentIndex] = newName;
  }
  function handleTyping(event) {
    //verifica se existe texto no input e deixa dar submit para a lista
    let hasText = !!event.target.value && event.target.value !== '';
    if(!hasText){
      clearInput();
      return;
    }
    if (event.key === 'Enter') {
      if(isEditing) {
        updateName(event.target.value);
      } else {
        globalNames.push(event.target.value);
      }
      render();
      isEditing = false;
      clearInput();
    }
  }
  inputName.focus();
  inputName.addEventListener('keyup', handleTyping);
}
function render() {
  //renderiza as informacoes do aray globalNames em forma de lista na tela, através de push e appendChild
  function createDeleteButton(index) {
    function deleteName() {
      // ppermite deletar o item da lista
      globalNames.splice(index, 1);
      render();
    }
    const button = document.createElement('button');
    button.textContent = 'x';
    button.classList.add('deleteButton');
    button.addEventListener('click', deleteName);
    return button;
  }
  function createSpan(name, index) {
    //cria o span onde o texto é armazenado
    function editItem() {
      //permite edicao do texto
      inputName.value = name;
      inputName.focus();
      isEditing = true;
      currentIndex = index;
    }
    let span = document.createElement('span');
    span.classList.add('clickable');
    span.textContent = name;
    span.addEventListener('click', editItem);
    return span;
  }
  let divNames = document.querySelector('#names');
  divNames.innerHTML = '';
  let ul = document.createElement('ul');
  for (let i = 0; i < globalNames.length; i++) {
    let currentName = globalNames[i];
    let li = document.createElement('li');
    let button = createDeleteButton(i);
    let span = createSpan(currentName, i)
    li.appendChild(button);
    li.appendChild(span);
    
    ul.appendChild(li);
  }
  divNames.appendChild(ul);
  clearInput();
}
function clearInput() {
  //limpa o input box
  inputName.value = '';
  inputName.focus();
}
//script a ser executado quando a página for carregada
function start() {
  //apelidos
  inputName = document.querySelector('#inputName');
  //açoes a serem executadas
  preventFormSubmit();
  activateInput();
  render();
}
start();
Aula 10 - JavaScript moderno – Introdução
A partir do ECMAScript6 o JS introduz alguns conceitos novos:
· Declaração de variáveis: var, const e let;
· Arrow functions;
· Template literals;
· Default parameters;
O código a seguir demonstra estas novas características:
'use strict';
//vas x let x const
//var tem escopo abrangente;
function withVar() {
  for (var i = 0; i < 10; i++) {
    console.log('var - ' + i);
  }
  i = 'sou o "i" criado dentro do loop for';
  console.log('sou o consolog fora do loop for: ' + i + '. withVar()');
}
//let tem escopo reduzido;
function withLet() {
  for (let i = 0; i < 10; i++) {
    console.log('let: ' + i);
  }
  i = 'sou o "i" criado dentro do loop for';
  console.log('sou o consolog fora do loop for: ' + i + '. withLet()');
}
//const
const c = 10;
console.log(c);
c = 5; //Uncaught TypeError: Assignment to constant variable.
console.log(c);
//execução
withVar();
withLet(); //Uncaught ReferenceError: i is not defined
E aqui o arrow function, default parameters e template literals:
//arrow function
const sumArrow1 = (a, b) => {return sum(a,b);};
//ou quando só tem um return
const sumArrow2 = (a, b) =>  a + b;
//template literals
const nome = 'Leo';
const texto = `Meu nome é ${nome}`;
console.log(texto); //Meu nome é Leo
//default parameters
const 
Aula 11 - JavaScript moderno - Manipulação de arrays
Aqui são demonstrados os principal métodos de manipulação de arrays que o JS oferece:
· map : (Gera um novo array, transformando dados);
· filter : (Gera um novo array filtrando elementos conforme condição);
· forEach (percorre todos os elementos do array aplicando uma lógica/função);
· reduce : (realiza cálculo iterativo com base nos elementos);
· find : (encontra o primeiro elemento de acordo com critério pré-definido);
· some : (retorna booleano se há pelo menos um elemento que atenda à preposição);
· every : (retorna booleano se todos os elementos atendem à preposição);
· sort : (Ordena os elementos com base em um critério);
//função que é executada ao iniciar a página
function start() {
  console.log('.map(): ',doMap());
  console.log('.filter(): ',doFilter());
  console.log('.forEach(): ',doForEach());
  console.log('.reduce(): ',doReduce());
  console.log('.find(): ',doFind());
  console.log('.some(): ',doSome());
  console.log('.every(): ',doEvery());
  console.log('.sort(): ',doSort());
}
//execução da página
start();
//Demonstração dos métodos de arrays mais importantes:
function doMap() {
  const nameEmailArray = people.results.map((person) => {
    return {
      name: `${person.name.first} ${person.name.last}`,
      email: person.email,
    };
  });
  return nameEmailArray;
}
function doFilter() {
  const olderThan50 = people.results.filter((person) => {
    return person.dob.age >= 50;
  });
  return olderThan50;
}
function doForEach() {
  const mappedPeople = doMap();
  let res = [];
  const nameSize = mappedPeople.forEach((person) => {
    res.push({ name: person.name, nameLength: person.name.length });
    return res;
  });
  return res;
}
function doReduce() {
  const totalAges = people.results.reduce((accumulator, current) => {
    return accumulator + current.dob.age;
  }, 0);
  return totalAges;
}
function doFind() {
  const mo = people.results.find((person) => {
    return person.location.state == 'Minas Gerais';
  });
  return mo;
}
function doSome() {
  const mo = people.results.some((person) => {
    return person.location.state == 'Amazonas';
  });
  return mo;
}
function doEvery() {
  const every = people.results.every((person) => {
    return person.nat == 'BR';
  });
  return every;
}
function doSort() {
  const mappedPeople = people.results.map((person) => {
    return { name: person.name.first };
  });
  const filteredPeople = mappedPeople.filter((person) =>
    person.name.startsWith('A')
  );
  const sortedPeople = filteredPeople.sort((a, b) => {
    return a.name.length - b.name.length;
  });
  return sortedPeople;
}
Aula 12 - JavaScript moderno - Rest/Spread operator e destructuring
O operador ‘...’ é responsável pela manipulação de elementos dentro de um array.
· O spread pega um array e ‘espalha’ ele dentro de um array ou algumoutro lugar;
· O rest serve para pegar infinitos argumentos em um único array;
· O destructuring é um jeito amis fácil de se pegar vária propriedades de uma variável em apenas uma linha;
function start() {
  doSpread();
  doRest(1,2,3,4);
  doDestructuring();
}
start();
//----------
function doSpread() {
  const marriedMen = people.results.filter(person => person.name.title == 'Mr');
  const marriedWomen = people.results.filter(person =>  person.name.title == 'Ms');
  const marriedPeople = [...marriedMen, ...marriedWomen];
  console.log(marriedPeople);
};
function doRest(...numbers) {
  let sum = numbers.reduce((acc, curr) => acc + curr, 0);
  
  console.log(numbers);
  console.log(sum);
};
function doDestructuring () {
  const first = people.results[0];
  const { username, password } = first.login;
  console.log(username, password);
  //invés de
  const usernameR = people.results[0].login.username;
  const passwordR = people.results[0].login.password;
  console.log(usernameR, passwordR);
};
Aula 13 - Refatoração do projeto de CRUD 
Aula 14 - Introdução à programação assíncrona com JavaScript
teoria
Aula 15 - Funções setTimeout e setInterval
· O setTimeOut() funciona para postergar uma execução de alguma coisa, ele executa o código dentro dela após tanto tempo a ser definico;
· O setTimeInterval serve para executar um código de tanto em tanto tempo;
function start() {
  const timer = document.getElementById('timer');
  const text = document.getElementById('text');
  let count = 0;
  const interval = setInterval(() => {
    timer.textContent = count++;
    if (count == 4) {
      this.clearInterval(interval); //Para a contagem
    }
  }, 500);
  setTimeout(() => {
    text.textContent = 'setTimeOut() funcionou';
  }, 2500);
}
start();
Aula 16 - Requisições HTTP com JavaScript
O '.fetch()' é uma função que retorna uma promise, por isso deve-se traalhar de maneira assíncrona com ele. “assim que este '.fetch()' estiver resolvido faça tal coisa”. Sendo que o ‘.catch()’ é usado quando o '.fetch()' encontra algum problema com a requisição e o ‘.then()’ quando a requisição funciona. 
function start(){
  doFetch();
  divisionPromise(2,0).then((result) => {
    console.log(result);
  }).catch((err) => {
    console.log('este foi o erro: ' + err);
  })
  asyncDivisionPromise();
  asyncDoFetch();
}; 
start();
//----------
function doFetch() {
  fetch('https://api.github.com/users/leomac00').then((res) => {
    res
      .json()
      .then((data) => {
        showData(data);
      })
      .catch((err) => {
        console.log(err);
      });
  });
}
function showData(data) {
  const user = document.getElementById('user');
  user.textContent = data.login + ' : ' + data.name;
}
function divisionPromise(a, b) {
  return new Promise((resolve, reject) => {
    if (b == 0) {
      reject('nao dá para dividir por zero');
    }
    resolve(a / b);
  });
}
async function asyncDivisionPromise() {
  const division = await  divisionPromise(2,2);
  console.log(division);
}
async function asyncDoFetch() {
  const res = await fetch('https://api.github.com/users/leomac00');
  const json = await res.json();
  console.log(json.name);
}
O ‘async’ e ‘await’ deve ser utilizado quando lidando com promises para poder facilitar o entendimento do código.
MÓDULO 02
Aula 01 – Apresentação do curso
Aula 02 – Conceitos e termos
Aula 03 - Instalação do Node.js - Visual Studio Code
Para poder utilizar o react é necessário instalar algumas dependências, sendo elas: 
· NVM que pode ser baixado por este link: https://github.com/nvm-sh/nvm ;
· Node.js – utilizando o nvm, que irá gerenciar as versões do node no computador, através do comando no cmd nvm install <version>, neste caso utilizaremos a 14.15.1;
Aula 04 - Primeira App React
Primeiramente deve-se iniciar o projeto React, para isto basta entrar no diretório em que se deseja criar o projeto pelo cmd e digitar, no exemplo criaremos o projeto ‘hello_world’ através do npx, instalando-o utilizando comando:
· npm install -g npx
Após instalado criamos o projeto:
· npx create-react-app hello_world
Então entrando no diretório criado é possível utilizar um comando para iniciar a aplicação;
· npm start
Aqui vale mostrar alguns comandos possíveis de serem executados ao se criar um novo app React:
· npm start: inicia o projeto em um servidor local;
· npm build: ‘constrói’ a aplicação pra poder ser enviada para a produção, ou seja, altera nomes de variáveis, exclui dependências de desenvolvimento ou desnecessárias e etc;
· npm eject: torna o gerenciamento de dependências manual;
Aula 05 - Conhecendo nossa App
Parte 01:
A primeira coisa a se notar quando abrir a app no VSCode é o package.json, que é responsável por manipular os script que podem ser rodados no terminal e gerenciar as dependências do projeto.
As dependências do projeto ficam instaladas na pasta node_modules dentro da pasta da aplicação.
Caso as dependências se percam ou precisem ser instaladas por alguma razão basta ir até a pasta onde está a aplicação, ou seja, onde está o package.json e rodar o seguinte comando no terminal:
· npm install
o comando irá ler o arquivo package.json e instalar todo o conteúdo necessário para rodar a aplicação. Isto pode ser usado também caso haja algum problema com alguma(s) da(s) dependências.
Parte 02:
Outro ponto a se notar nos arquivos é a pasta public, ela contém todos os arquivos responsáveis pela página, por exemplo o index.html e index.js.
Uma coisa legal de se notar aqui é que possível rodar o React em apenas uma parte da página. Para isso é necessário criar uma div onde se quer que seja executada, no caso do projeto pré-existente a div ‘root’ e então indicar que o React deve ser executado nela no index.js.
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
    <title>React App</title>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
  </body>
</html>
E no js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);
reportWebVitals();
Alguns arquivos também podem ser apagados, como é o caso das imagens que o create-react-app cria automaticamente e afins, por exemplo, só que qualquer modificação feita nestes arquivos, exclusão ou inclusão, deve ser editada no arquivo ./public/manifest.json. E praticamente a todo o conteúdo da pasta ./src pode ser apagada.
O componente React reponsável por renderizar as informações na tela é o ReactDOM, que recebe dois parâmetros:
1. O que irá renderizar;
2. Onde irá renderizar;
E para que ele funcione ele deve ser importado através do import.
Aula 06 - Calculadora
Parte 01:
A intenção desta aula é aprender o básico de React e o básico de CSS.
Aqui se faz importante freezar que se pode utilizar o React apenas em um pedacinho da página através do ReacDOM.render();
Trabalhando com React é uma boa prática criar uma pasta ./src/componentes para armazenar todos os componentes que não são containers, isto é, de forma que esses componente que fazem parte da página possam ficar melhor organizados, por exemplo um arquivo com as funcionalidades da calculadora.
De maneira análoga se cria uma pasta ./src/containers, para armazenar os container, no caso, cria-se um arquivo chamado calculator.js para armazenar a calculadora.
Outra boa prática ser observada é a de planejar antes de fazer, mesmo parecendo óbvio, costuma-se primeiro criar os arquivos e pastas necessários antes de coda-los. No exemplo, é possível observar que a calculadora possui três componentes principais:Os botões, o display e a calculadora em si. Portanto, organizam-se os elementos da seguinte maneira:
Agora dando início ao código:
Código do arquivo display.js:
//Importa do React a classe Components
import React, { Component } from 'react';
//Cria uma classe Display que é uma extensão de Components
class Display extends Component {
  //render() é a função no React.js responsável por renderizar alguma informação para o usuário
  render() {
    //no caso irá renderizar uma div com tais classes e tais valores
    return (
    <div className={"display borderBlack"}>
      {this.props.value}
    </div>
    )
  }
}
//usando 'export default' não será necessário usar '{}' na hora de importar
export default Display;
Perceba que o método render() retorna um HTML que é escrito em JSX (HTML + JSX).
Parte 02:
“A ideia de separar em vários componentes é dividir responsabilidades.”
Código do arquivo button.js:
import React, { Component } from 'react';
class Button extends Component {
  handleClick() {
    if (this.props.onClick){
      this.props.onClick();
    }
  }
  render() {
    return(
    <div className={"button"} onClick={this.handleClick.bind(this)}>
      {this.props.display}
    </div>
    )
  }
}
export default Button;
Código do arquivo calculator.js:
import {Component} from 'react';
import Button from '../components/button';
import Display from '../components/display';
class Calculator extends Component {
  render() {
    return (
      <div className={"calculator"}>
        <Display value={"1234567890"}/>
        <Button display={"1"}/>
        <Button display={"2"}/>
        <Button display={"3"}/>
        <Button display={"4"}/>
        <Button display={"5"}/>
        <Button display={"6"}/>
        <Button display={"7"}/>
        <Button display={"8"}/>
        <Button display={"9"}/>
        <Button display={"0"}/>
        <Button display={"+"}/>
        <Button display={"-"}/>
        <Button display={"="}/>
        <Button display={"C"}/>
      </div>
    )
  }
}
export default Calculator;
Código do arquivo App.js:
import React from 'react';
import Calculator from './containers/calculator'
export function App() {
  return (
    <div className="scren">
      <Calculator/>
    </div>
  )
}
Código do arquivo index.js:
import React from 'react';
import ReactDOM from 'react-dom';
import {App} from './App';
ReactDOM.render(
  <App/>,
  document.getElementById('root')
);
Aula 07 - Estilizando a nossa calculadora
Parte 01:
Para estilizar uma aplicação React trabalha-se com o CSS de maneira análoga a quando se trabalha com estilizando direto a página HTML porém já que o HTML é criado nos scripts JS deve ser levado em conta este ao invés do HTML em si, por isso é necessário importar o CSS dentro do arquivo JS que cria o HTML a ser usado.
No index.js:
import React from 'react';
import ReactDOM from 'react-dom';
import {App} from './App';
import "./index.css";
ReactDOM.render(
  <App/>,
  document.getElementById('root')
);
No app.js:
import React from 'react';
import Calculator from './containers/calculator';
import './app.css';
export function App() {
  return (
    <div className="screen">
      <div className="divSup"/>
      <Calculator />
      <div className="divInf"/>
    </div>
  );
}
No caso o reset do CSS foi feito no index.js e a estilização do app foi feito no app.css e app.js.
Noções de Grid no CSS:
O Grid do CSS tem por objetivo dividir a tela em frações determinadas pelo dev. No exemplo da calculadora decide-se utilizar uma divisão de linhas de ‘10fr 80fr 10fr’ onde ‘fr’ representa a fração das telas. E para fazer com que a implementação deste código CSS seja feita em toda a vista (view) é necessário determinar que o Height seja igual a 100vh (100% de view height), chegando em:
No app.css:
.screen {
  display: grid;
  grid-template-rows: 10fr 80fr 10fr;
  height: 100vh;
}
Parte 02: 
Aqui é importate freezar que o grid-template-columns divide a tela de maneira horizontal, e o grid-template-rows de maneira vertical.
Com isso em mente utilizamos o rows e o columns para centralizar a calculadora na página.
No app.css:
.screen {
  display: grid;
  /* Cria  3 linhas e 3 colunas nas frações indicadas */
  grid-template-rows: 10fr 80fr 10fr;
  grid-template-columns: 35fr 30fr 35fr;
  height: 100vh;
}
.calculator {
  /* Insere os elementos da div 'calculator' na coluna 2, linha 2 */
  grid-column: 2;
  grid-row: 2;
  border: 1px solid black;
  border-radius: 5%;
  padding: 1em;
}
.button {
  display: grid;
  place-items: center;
  width: 3em;
  height: 3em;
  border: 1px solid black;
}
Parte 03:
Aqui consertamos a disposição dos botões na tela para que fiquem centralizados e ao usar o flex-wrap: wrap os botões quando chegarem ao final de seu container eles comecem no inicio dele na próxima linha:
.screen {
  display: grid;
  /* Cria  3 linhas e 3 colunas nas frações indicadas */
  grid-template-rows: 10fr 80fr 10fr;
  grid-template-columns: 35fr 30fr 35fr;
  height: 100vh;
}
.calculator {
  /* Insere os elementos da div 'calculator' na coluna 2, linha 2 */
  grid-column: 2;
  grid-row: 2;
  border: 1px solid black;
  border-radius: 5%;
  padding: 1em;
  /* Terá altura máxima de 100% da calculadora e tudo que passar (overflow) estará escondido (hidden) */
  max-height: 100%;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.button {
  display: grid;
  margin: 1em;
  place-items: center;
  width: 3em;
  height: 3em;
  border: 1px solid black;
  background-color: brown;
  color: white;
}
.buttonsContainer {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-wrap: wrap;
  background-color: burlywood;
}
Parte 04:
Apenas terminamos de estilizar o código obtendo:
.screen {
  display: grid;
  /* Cria  3 linhas e 3 colunas nas frações indicadas */
  grid-template-rows: 10fr 80fr 10fr;
  grid-template-columns: 35fr 30fr 35fr;
  height: 100vh;
}
.calculator {
  /* Insere os elementos da div 'calculator' na coluna 2, linha 2 */
  grid-column: 2;
  grid-row: 2;
  border: 1px solid black;
  border-radius: 5%;
  padding: 1em;
  /* Terá altura máxima de 100% da calculadora e tudo que passar (overflow) estará escondido (hidden) */
  max-height: 100%;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.button {
  display: grid;
  margin: 1em;
  place-items: center;
  width: 3em;
  height: 3em;
  border: 1px solid black;
  background-color: brown;
  color: white;
  cursor: pointer;
}
.buttonsContainer {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-wrap: wrap;
  background-color: burlywood;
  border: 2px solid rgb(48, 156, 80);
}
.display {
  display: flex;
  justify-content: flex-end;
  border: 1px solid black;
  background-color: violet;
  color: white;
}
 
Aula 08 - Dando funções à nossa Calculadora
Parte 01:
Agora voltamos a mexer com o JS do react de fato.
Toda classe em React possui um estado inicial que deve ser setada no constructor da classe.
Aqui ainda fazemos o display mostrar o valor através da função getValue() e usamos a função putValue() para pegar o valor quando clicado nos botões através do onCLick() neles.
import { Component } from 'react';
import Button from '../components/button';
import Display from '../components/display';
class Calculator extends Component {
  initialState = { firstValue: 0, secondValue: 0 };
  constructor(props) {
    super(props); //Faz herdar o 'props' do Component
    this.state = this.initialState;
  }
  putValue = (value) => {
    const lastValue = this.state.firstValue;
    this.setState({ firstValue: lastValue * 10 + value });
  };
  getValue = () => {
    return this.state.firstValue;
  };
  render() {
    return (
      <div className={'calculator'}>
        <div>
          <Display value={this.getValue()} />
        </div>
        <div className="buttonsContainer">
          <Button display={'1'} onClick={() => this.putValue(1)} />
          <Button display={'2'} onClick={() => this.putValue(2)} /><Button display={'3'} onClick={() => this.putValue(3)} />
          <Button display={'4'} onClick={() => this.putValue(4)} />
          <Button display={'5'} onClick={() => this.putValue(5)} />
          <Button display={'6'} onClick={() => this.putValue(6)} />
          <Button display={'7'} onClick={() => this.putValue(7)} />
          <Button display={'8'} onClick={() => this.putValue(8)} />
          <Button display={'9'} onClick={() => this.putValue(9)} />
          <Button display={'0'} onClick={() => this.putValue(0)} />
          <Button display={'+'} />
          <Button display={'-'} />
          <Button display={'='} />
          <Button display={'C'} />
        </div>
      </div>
    );
  }
}
export default Calculator;
Parte 02:
Aqui trabalhamos as operações que podem ser executadas com a calculador, utilizando o operator que será uma variável introduzida no initialState para guardar qual operação está sendo executada.
import { Component } from 'react';
import Button from '../components/button';
import Display from '../components/display';
class Calculator extends Component {
  initialState = { firstValue: 0, secondValue: 0, operator: 1, isSum: false };
  constructor(props) {
    super(props); //Faz herdar o 'props' do Component
    this.state = this.initialState;
  }
  putValue = (value) => {
    const {firstValue, secondValue, operator} = this.state;
    const lastValue =
      operator === 1
        ? firstValue
        : secondValue;
    switch (operator) {
      case 1:
        this.setState({ firstValue: (lastValue * 10) + value });
        break;
      case 2:
        this.setState({ secondValue: (lastValue * 10) + value });
        break;
    }
  };
  getValue = () => {
    const {firstValue, secondValue, operator, isSum} = this.state
    switch (operator) {
      case 1:
        return firstValue;
      case 2:
        return secondValue;
      case 3:
        return isSum
          ? firstValue + secondValue
          : firstValue - secondValue;
    }
  };
  pickOperation = (isSum) => {
    this.setState({ operator: 2, isSum });
  };
  execOperation = () => {
    this.setState({ operator: 3 });
  };
  clear = () => {
    this.setState(this.initialState);
  }
  render() {
    return (
      <div className={'calculator'}>
        <div>
          <Display value={this.getValue()} />
        </div>
        <div className="buttonsContainer">
          <Button display={'1'} onClick={() => this.putValue(1)} />
          <Button display={'2'} onClick={() => this.putValue(2)} />
          <Button display={'3'} onClick={() => this.putValue(3)} />
          <Button display={'4'} onClick={() => this.putValue(4)} />
          <Button display={'5'} onClick={() => this.putValue(5)} />
          <Button display={'6'} onClick={() => this.putValue(6)} />
          <Button display={'7'} onClick={() => this.putValue(7)} />
          <Button display={'8'} onClick={() => this.putValue(8)} />
          <Button display={'9'} onClick={() => this.putValue(9)} />
          <Button display={'0'} onClick={() => this.putValue(0)} />
          <Button display={'+'} onClick={() => this.pickOperation(true)} />
          <Button display={'-'} onClick={() => this.pickOperation(false)} />
          <Button display={'='} onClick={() => this.execOperation()}/>
          <Button display={'C'} onClick={() => this.clear()}/>
        </div>
      </div>
    );
  }
}
export default Calculator;
Parte 03:
Organizamos mais ainda o código e implementamos a função de desabilitar botões através do this.props.disabled
NO button.js:
import React, { Component } from 'react';
class Button extends Component {
  handleClick() {
    const { disabled, onClick } = this.props;
    if (onClick && !disabled) this.props.onClick();
  }
  render() {
    const cssButtonClass = this.props.disabled ? 'button disabled' : 'button';
    return (
      <div
        className={cssButtonClass}
        onClick={this.handleClick.bind(this)}
      >
        {this.props.display}
      </div>
    );
  }
}
export default Button;
No calculator.js:
import { Component } from 'react';
import Button from '../components/button';
import Display from '../components/display';
class Calculator extends Component {
  initialState = { firstValue: 0, secondValue: 0, operator: 1, isSum: false };
  constructor(props) {
    super(props); //Faz herdar o 'props' do Component
    this.state = this.initialState;
  }
  putValue = (value) => {
    const {firstValue, secondValue, operator} = this.state;
    const lastValue =
      operator === 1
        ? firstValue
        : secondValue;
    switch (operator) {
      case 1:
        this.setState({ firstValue: (lastValue * 10) + value });
        break;
      case 2:
        this.setState({ secondValue: (lastValue * 10) + value });
        break;
    }
  };
  getValue = () => {
    const {firstValue, secondValue, operator, isSum} = this.state
    switch (operator) {
      case 1:
        return firstValue;
      case 2:
        return secondValue;
      case 3:
        return isSum
          ? firstValue + secondValue
          : firstValue - secondValue;
    }
  };
  pickOperation = (isSum) => {
    this.setState({ operator: 2, isSum });
  };
  execOperation = () => {
    this.setState({ operator: 3 });
  };
  clear = () => {
    this.setState(this.initialState);
  }
  render() {
const {operator} = this.state;
    return (
      <div className={'calculator'}>
        <div>
          <Display value={this.getValue()} />
        </div>
        <div className="buttonsContainer">
          <Button display={'1'} onClick={() => this.putValue(1)} disabled={operator === 3}/>
          <Button display={'2'} onClick={() => this.putValue(2)} disabled={operator === 3}/>
          <Button display={'3'} onClick={() => this.putValue(3)} disabled={operator === 3}/>
          <Button display={'4'} onClick={() => this.putValue(4)} disabled={operator === 3}/>
          <Button display={'5'} onClick={() => this.putValue(5)} disabled={operator === 3}/>
          <Button display={'6'} onClick={() => this.putValue(6)} disabled={operator === 3}/>
          <Button display={'7'} onClick={() => this.putValue(7)} disabled={operator === 3}/>
          <Button display={'8'} onClick={() => this.putValue(8)} disabled={operator === 3}/>
          <Button display={'9'} onClick={() => this.putValue(9)} disabled={operator === 3}/>
          <Button display={'0'} onClick={() => this.putValue(0)} disabled={operator === 3}/>
          <Button display={'+'} onClick={() => this.pickOperation(true)} disabled={operator !== 1}/>
          <Button display={'-'} onClick={() => this.pickOperation(false)} disabled={operator !== 1}/>
          <Button display={'='} onClick={() => this.execOperation()}disabled={operator === 1}/>
          <Button display={'C'} onClick={() => this.clear()}/>
        </div>
      </div>
    );
  }
}
export default Calculator;
No index.css:
html,
body {
  margin: 0;
  padding: 0;
  width: 100%;
  height: 100%;
}
.disabled {
  background-color: gray;
}
Aula 09 - Axios
Teórica
Axios vs. Fetch
Aula 10 - Nossa APP
Links utilizados:
http://star-wars-brigolini.herokuapp.com/
https://swapi.dev/
https://github.com/brigolini/StarWars
https://bcherny.github.io/json-schema-to-typescript-browser/
https://app.quicktype.io/
Aula 11 – Design da App
Aqui estão algumas explicações sobre como será o design da App e como funciona a API de star wars
Aula 12 – Criando a App
Esta App funciona como uma especie de wikipedia do Star Wars.
Iniciamos a App criando o diretório através do 
•	npx create-react-app star_wars –-template typescript
A partir deste projeto será muito utilizado o typescript como linguagem principal. 
Uma coisa a se notar é que algumas configurações devem ser feitas, a primeira é no manifest.json é necessário que a propriedade JSX esteja como "jsx": "react". Após isto é de boa prática excluir os logos na pasta public e todo o conteúdo da pasta src exceto pelo reportWebVital.tsx.
Aula 13 - Criandoa instância do Axios
Aqui iremos criar as instancias do axios para poder fazer os requests para a api
import Axios, { AxiosInstance } from 'axios';
const baseURL = 'https://swappi.dev/api';
export const getAxiosInstance = (): AxiosInstance => {
  let axiosInstance = Axios.create({ baseURL: baseURL });
  axiosInstance.interceptors.response.use(
    (response) => response, //retorna response se houver response
    (error) => { //se tiver erro e esse erro tiver status maior que 399 retorna a mensagem abaixo
      const { status } = error.response;
      if (status > 399) console.info(`Erro na API. Status: ${status}`);
    }
  );
  return axiosInstance;
};
Aula 14 - Aula teórica : Promisses
Promises são pedaços do código que são executados após todo o código que não é promises for executado, este é o conceito de programação assíncrona.
Lembrando que ‘todo GET retorna uma promisse’. 
Aula 15 - Iniciando a nossa controller genérico
Agora precisamos criar o controller que será responsável por receber os schemas da api.
Para isso precisamos fazer um axios.get nos schemas da api, então simplesmente escrevemos:
No generic-api.ts
import Axios from "axios";
import { getAxiosInstance } from "../axios-instance";
export type SWAPIEndpoint = 'people' | 'films' | 'startships' | 'vehicles' | 'species' | 'planets';
export const genericController = (endpoint: SWAPIEndpoint) => {
  const axios = getAxiosInstance();
  const getSchema = async () => {
    const response = await axios.get(`/${endpoint}/schema`);
    return response.data;
  }
  return {getSchema}
}
Aula 16 - Testando a nossa função de Schema
Para testar a função getSchema retornada pelo genericController precisamos atribuir ela a uma variável para ser usada. Apó atribuído a ideia é setar um valor para uma variável criada schema para poder mostrar na tela e ver se está tudo ok com o axios criado para lidar com a API; lembrando que toda vez que uma função retorna uma promises ela deve ser acrescida de .then() ou o await/async.
No app.tsx
import React, { useState } from 'react';
import { genericController } from './api/generic-api';
export const App = () => {
  //cria-se a variável schema e a função setSchema para lidar com ela e neste exemplo só retorna o description
  const [schema, setSchema] = useState({description:''});
  //de genericController desestruturamos para pegar a função getSchema, de 'people' desta vez para usar como teste
  const {getSchema} = genericController('people');
  //Usamos getSchema que após ter a promise fullfilled retorna o valor da key description de people e através de setSchema atualizamos seu valor.
  getSchema().then(
    valor => setSchema(valor)
    )
    //renderiza o valor armazenado na variável schema
  return <div> {schema.description} </div>
};
Aula 17 - Criando e testando a nossa função getByld
Agora iremos fazer o mesmo processo, mas para o ID do item na API.
Ainda implementamos uma interface para garantir que o tipo que está sendo usado e devolvido é o do utilizado pela função.
Após isto direcionamos a atenção para o app.tsx, onde pegamos a função criada getByID e usamos novamente o setSchema para dar um valor ao schema para renderizá-lo. Aqui temos que resolver um problema gerado na execução do novo estado que cria um loop infinito (pois quando um novo estado é gerado a função inicia novamente e entra num loop) e para isso usamos o useEffect, que recebe dois argumentos e dita a quantidade de vezes que o primeiro argumento será executado.
No generic-api.ts:
import { getAxiosInstance } from "./axios-instance";
export type SWAPIEndpoint = 'people' | 'films' | 'startships' | 'vehicles' | 'species' | 'planets';
export interface ResourceReturn {
  getSchema:() =>void;
  getByID:(id: number) => Promise<any>
}
export const genericController = (endpoint: SWAPIEndpoint) => {
  const axios = getAxiosInstance();
  const getSchema = async () => {
    const response = await axios.get(`/${endpoint}/schema`);
    return response.data;
  }
  const getByID = async (id: number) => {
    const response = await axios.get(`/${endpoint}/${id}`);
    return response.data;
  }
  return {getSchema, getByID}
}
No app.tsx:
import React, { useEffect, useState } from 'react';
import { genericController } from './api/generic-api';
export const App = () => {
  
  const [schema, setSchema] = useState({name:''});
  const {getByID} = genericController('people');
  useEffect(() => {
    getByID(1).then(
      valor => setSchema(valor)
      )
  })
    
  return <div> {schema.name} </div>
};
Aula 18 - Entendendo Generics
Nesta aula introduz-se o conceito de generics que é basicamente um jeito de ‘tipar’ de maneira genérica o resultado da promises, no exemplo dado, se você der request em algo do tipo ‘People’ ele vai retornar uma promises do tipo ‘People’. 
Isto é interessante por permite uma manutenção mais fácil do código posteriormente e isso garante que seu controller não receba valores erados.
Dito isso vamos ao código:
No generic-api.ts:
import { getAxiosInstance } from "./axios-instance";
export type SWAPIEndpoint = 'people' | 'films' | 'startships' | 'vehicles' | 'species' | 'planets';
export interface ResourceReturn<T> {
  getSchema:() =>void;
  getByID:(id: number) => Promise<T>
}
export const genericController = <T>(endpoint: SWAPIEndpoint):ResourceReturn<T> => {
  const axios = getAxiosInstance();
  const getSchema = async () => {
    const response = await axios.get(`/${endpoint}/schema`);
    return response.data;
  }
  const getByID = async (id: number):Promise<T> => {
    const response = await axios.get(`/${endpoint}/${id}`);
    return response.data;
  }
  return {getSchema, getByID}
}
No app.tsx:
import React, { useEffect, useState } from 'react';
import { genericController } from './api/generic-api';
import { People } from './api/schemas/people'
export const App = () => {
  //com esse novo atributo de tipo ele irá selecionar tudo do tipo passado para ele, no caso usamos People para testar
  const [schema, setSchema] = useState<People>();
  const {getByID} = genericController<People>('people');
  useEffect(() => {
    getByID(1).then(
      valor => setSchema(valor)
      )
  })
    //aqui implementamos apenas um teste para saber se o schema existe
  return <div> {schema?schema.name:null} </div>
};
Aula 19 – GetAll
Parte 01:
Começamos definindo o tipo de dados que o getAll pode retornar.
No generic-api.ts
import { getAxiosInstance } from "./axios-instance";
export type SWAPIEndpoint = 'people' | 'films' | 'startships' | 'vehicles' | 'species' | 'planets';
export interface PageData {
  proximo: number | null;
  anterior: number | null;
  total: number;
  totalRegistros: number;
}
export interface PageableResponse<T> {
  dados: T[];
  page: PageData;
}
export interface ResourceReturn<T> {
  getSchema:() =>void;
  getByID:(id: number) => Promise<T>;
  getAll: (page: number) => Promise<PageableResponse<T>>;
}
export const genericController = <T>(endpoint: SWAPIEndpoint):ResourceReturn<T> => {
  const axios = getAxiosInstance();
  const getSchema = async () => {
    const response = await axios.get(`/${endpoint}/schema`);
    return response.data;
  }
  const getByID = async (id: number):Promise<T> => {
    const response = await axios.get(`/${endpoint}/${id}`);
    return response.data;
  }
  return {getSchema, getByID}
}
Parte 02:
Aqui criamos as funções getPageNumber e getPageData para trazer os dados da página para a função getAll que é responsável por pegar todos os dados da página.
No generic-api.ts
import { AxiosResponse } from "axios";
import { getAxiosInstance } from "./axios-instance";
export type SWAPIEndpoint = 'people' | 'films' | 'startships' | 'vehicles' | 'species' | 'planets';
export interface PageData {
  proximo: number | null;
  anterior: number | null;
  total: number;
  totalRegistros: number;
}
export interface PageableResponse<T> {
  dados: T[];
  page: PageData;
}
export interface ResourceReturn<T> {
  getSchema: () => void;
  getByID: (id:number) => Promise<T>;
  getAll: (page: number) => Promise<PageableResponse<T>>;
}
export const genericController = <T>(endpoint: SWAPIEndpoint): ResourceReturn<T> => {
  const axios = getAxiosInstance();
  const getSchema = async () => {
    const response = await axios.get(`/${endpoint}/schema`);
    return response.data;
  }
  const getByID = async (id: number): Promise<T> => {
    const response = await axios.get(`/${endpoint}/${id}`);
    return response.data;
  }
  const getAll = async (pageNumber: number): Promise<PageableResponse<T>> => {
    const response = await axios.get(`/${endpoint}/?page=${pageNumber}`);
    const dados: T[] = response.data.results;
    const page: PageData = getPageData(response);
    return {page, dados};
  }
  const getPageData = (response: AxiosResponse): PageData => {
    const proximo: number | null = getPageNumber(response.data.next);
    const anterior: number | null = getPageNumber(response.data.previous);
    const resultSize = response.data.results.length;
    const count = response.data.count;
    const total: number = (count % resultSize) === 0 ? (count / resultSize) : Math.floor(count / resultSize) + 1;
    return {proximo, anterior, total, totalRegistros: count}
  }
const getPageNumber = (url: string | null): number | null => {
  if(!url) return null;
  const matchs = url.match(`page=\\d+`);
  if(matchs) return parseInt(matchs[0].replace('page=',''));
  return null;
}
  return { getSchema, getByID, getAll }
}
Parte 03: 
Agora começamos a testar o método getAll que será importado par ao arquivo App.tsx.
Aqui é interessante salientar o uso do React fragmente que permite o navegador entender apenas um elemento pai do tipo div para que mais de uma div possa ser carregada na hora de renderizar.
import React, { useEffect, useState } from 'react';
import { genericController, PageData } from './api/generic-api';
import { People } from './api/schemas/people'
export const App = () => {
  const { getAll } = genericController<People>('people');
  const [people, setPeople] = useState<People[]>();
  const [page, setPage] = useState<PageData>();
  useEffect(() => {
    getAll(1).then(
      valor => {
        setPeople(valor.dados)
        setPage(valor.page)
      }
  )}, [])
  if (people) {
    return (
      <>
        <div>Paginação: Anterior: {page?.anterior} - Próximo: {page?.proximo} </div>
        {people.map(person => <div>{person.name}</div>)}
      </>
    );
  } else {
    return (<div></div>);
  }
};
Aula 20 - Criando nosso GetByPartialName
Agora está praticamente terminada toda a interface para pegar os dados da API. Então podemos começar a focar na parte gráfica.
Mas primeiro ciramos uma função para pegar um dado de uma página X pelo partial Name.
No generic-api.tsx
import { AxiosResponse } from "axios";
import { getAxiosInstance } from "./axios-instance";
export type SWAPIEndpoint = 'people' | 'films' | 'startships' | 'vehicles' | 'species' | 'planets';
export interface PageData {
  proximo: number | null;
  anterior: number | null;
  total: number;
  totalRegistros: number;
}
export interface PageableResponse<T> {
  dados: T[];
  page: PageData;
}
export interface ResourceReturn<T> {
  getSchema: () => void;
  getByID: (id: number) => Promise<T>;
  getAll: (page: number) => Promise<PageableResponse<T>>;
  getByPartialName: (searchTerm: string, pageNumber: number) => Promise<PageableResponse<T>>;
}
export const genericController = <T>(endpoint: SWAPIEndpoint): ResourceReturn<T> => {
  const axios = getAxiosInstance();
  const getSchema = async () => {
    const response = await axios.get(`/${endpoint}/schema`);
    return response.data;
  }
  const getByID = async (id: number): Promise<T> => {
    const response = await axios.get(`/${endpoint}/${id}`);
    return response.data;
  }
  const getAll = async (pageNumber: number): Promise<PageableResponse<T>> => {
    const response = await axios.get(`/${endpoint}/?page=${pageNumber}`);
    const dados: T[] = response.data.results;
    const page: PageData = getPageData(response);
    return {page, dados};
  }
  const getByPartialName = async (searchTerm: string, pageNumber: number): Promise<PageableResponse<T>> => {
    const response = await axios.get(`/${endpoint}/?search=${searchTerm}/?page=${pageNumber}`);
    const dados: T[] = response.data.results;
    const page: PageData = getPageData(response);
    return {dados, page};
  };
E então para a próxima aula intalamos o matéria-ui/core usando o npm install.
Aula 21 – Aula teórica: Hooks
“Hooks veio parar separar a regra de negocia da renderização. “
A partir da versão 16.8 do React foi introduzido o hooks que é um componente externo ao componente que será renderizado que tem a regra de negócio para alterar o componente renderizável.
Esses hooks são funções do React que fazem essa leitura de estado e alteram, de alguma maneira, a renderização.
· useState: 
const [state, setState] = useState(initialState);
Retorna um valor e uma função para atualizar o valor.
· useEffect: 
useEffect(didUpdate);
Aceita uma função que contém um código imperativo, possivelmente efetivo. Por padrão, os efeitos são executados após cada renderização concluída, mas você pode optar por dispará-los somente quando determinados valores receberam atualização.
· useMemo:
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
É usado para aumentar a performance, o useMemo salva um determinado valor e usa esse valor até que haja uma modificação nos parâmetros observados. No exemplo ele só chama a função computerExpensiveValue() quando houver alteração nos valores dentro do array passado sempre como segundo argumento.
· useCallBack:
const memoizedCallback = useCallback(() => { doSomething(a, b);}, [a, b]);
Basicamente a mesma coisa que o useMemo, faz alguma coisa quando houve alteração nos valore sobservados.
É importante lembrar que sempre que um hook é alterado o componente é renderizado novamente.
Hook adiciona complexidade, e não pode ser cirado dentro de laços e dentro de funções ou condicionais.
Aula 22 - Material UI
Material UI é uma biblioteca gráfica que pode ser utilizada no desenvolvimento.
É baseada no https://material.io/design . 
Aula 23 – TypeScript
TS é a versão tipada de JS, ou seja, é possível colocar tipos para parâmetros e variáveis do JS.
Isso facilita no uso de grandes equipes, na escalabilidade do código e a segurança que os tipos trazem.
Aula 24 - Apresentando o componente Detalhe
Aqui começamos a escrever o novo componente que será responsável por mostrar os detalhes das informações que se quer mostrar.
Src/componentes/detalhe.tsx 
import React from "react";
import { SWAPIEndpoint } from "../../api/generic-api";
import {CircularProgress} from "@material-ui/core";
interface DetalheProps {
  id: number,
  controller: SWAPIEndpoint,
}
const Detalhe = (props: DetalheProps) => {
  const { id, controller } = props;
  const {isLoading, result, error} = useDetalhe(id, controller);
  if(isLoading) return <div><CircularProgress/></div>
  if(!result) return null;
return (
);
};
Perceba que ainda não foi criado o componente use-detalhe mas já trabalhamos com ele como se estivesse pronto pois assim que estiver ele irá funcionar.
Aula 25 - Criando a estrutura genérica de dados
Aqui vale lembrar que uma função do tipo getter pode acabar retornando recebendo um valor undefined e caso não consiga tratar este valor pode dar algum problema por isso é sempre interessante que se cheque se o valor pego existe, caso não exista deve retornar null caso contrario deve continuar com a função.
Aqui criamos o getDetailData que nos traz as colunas que devem ser mostradas ao selecionar um tipo de informação para pesquisar
No controller-defs.ts
import { SWAPIEndpoint } from "./generic-api";
interface ControllerDefs {
  detailData: string[];
}
const controllerData : Map<string, ControllerDefs> = new Map();
controllerData.set(`people`,{
  detailData:[`name`, `mass`,`hair_color`,`skin_color`,`gender`]
})
controllerData.set(`films`,{
  detailData: [`title`,`director`,`producer`,`opening_crawl`]
})
export const getDetailData = (controller:SWAPIEndpoint):string[] | null => {
  const coluna = controllerData.get(controller);
  if(!coluna) return null;
  return coluna.detailData;
}
Aula 26 – Componente de detalhe
Parte 01:
Aqui começamos a codar a parte de renderização dos campos para cada item.
Para isso criamos dois elementos <Grid>, que vem do material-ui, um deles contendo o botão de voltar e o outro contendo os items encontrados.
O botão é bem simples, o código inserido ali é um <Button> que vem do material-ui.
Já o grid com as informações usamos um Object.entries para retornar um array das propriedades de chave/valor de um determinado objeto, no caso de ‘result’. Então filtramos os valores trazidos pelo resultado para que ele bata com os valores trazidos pelo getDetailData() e então usamos o .map() para retornar um <Field>, que ainda será criado, para cada item filtrado do result conendo sua key (nome do campo) e seu value (seu valor).
No detalhe.tsx:
import React from 'react';
import { SWAPIEndpoint } from '../../api/generic-api';
import { Button, CircularProgress, Grid } from '@material-ui/core';
import { getDetailData } from '../../api/controller-defs';
interface DetalheProps {
  id: number;
  controller: SWAPIEndpoint;
}
const Detalhe = (props: DetalheProps) => {
  const { id, controller } = props;
  const { isLoading, result, error } = useDetalhe(id, controller);
  const colunas = getDetailData(controller);
  if (isLoading)
    return (
      <div>
        <CircularProgress />
      </div>
    );
  if (!result) return null;
  return (
    <Grid container direction={'column'} spacing={2} alignItems={'stretch'}>
      <Grid>
        {Object.entries(result)
          .filter((item) => {
            const [key] = item;
            return colunas?.find((campo) => campo === key);
          })
          .map((item) => {
            const [key, value] = item;
            return <Field nome={key} value={value} />;
          })}
      </Grid>
      <Grid>
        <Button variant={'outlined'}>Voltar</Button>
      </Grid>
    </Grid>
  );
};
Parte 02:
Agora montamos o render accordion que será responsável por mostrar o sumário e o detail dos valores que forem puxados da API.
No detalhe/field.tsx:
import { Accordion, AccordionDetails, AccordionSummary, Grid } from "@material-ui/core";
import React from "react";
import ExpandMoreIcon from "@material-ui/icons/ExpandMore"
interface FieldProps {
  nome: string;
  valor: string;
}
export const Field = (props: FieldProps) => {
  const {nome, valor} = props;
  return (
    <Grid item xs={12}>
      <Accordion>
        <AccordionSummary
          expandIcon={<ExpandMoreIcon />}
          aria-controls="panella-content"
          id="panella-header">
        </AccordionSummary>
        <AccordionDetails>
        </AccordionDetails>
      </Accordion>
    </Grid>   
  );
}
No detalhe.tsx:
import React from 'react';
import { SWAPIEndpoint } from '../../api/generic-api';
import { Button, CircularProgress, Grid } from '@material-ui/core';
import { getDetailData } from '../../api/controller-defs';
import { Field } from './field';
interface DetalheProps {
  id: number;
  controller: SWAPIEndpoint;
}
const Detalhe = (props: DetalheProps) => {
  const { id, controller } = props;
  const { isLoading, result, error } = useDetalhe(id, controller);
  const colunas = getDetailData(controller);
  if (isLoading)
    return (
      <div>
        <CircularProgress />
      </div>
    );
  if (!result) return null;
  return (
    <Grid container direction={'column'} spacing={2} alignItems={'stretch'}>
      <Grid>
        {Object.entries(result)
          .filter((item) => {
            const [key] = item;
            return colunas?.find((campo) => campo === key);
          })
          .map((item) => {
            const [key, value] = item;
            return <Field nome={key} valor={value}/>;
          })}
      </Grid>
      <Grid>
        <Button variant={'outlined'}>Voltar</Button>
      </Grid>
    </Grid>
  );
};
Aula 27 - Criando o hook useAsync
Aqui criamos o useAsync para capturar os dados de isLoading, Error e result que são passados para a renderização dos items.
No useEffect, como segundoparametro passamos as dependências para que ele seja executado, dentro do array vao as funções setError, setIsLoading, setResult e asyncFn, dessa forma o useEffect só será rodado quando após cada uma das dependências for atualizada.
Só que existe um “porém”, o React, por definição não pode ter funções assincornas sendo executadas dentro dele, para brular este problema, criamos uma função foo() que executa o código asincorono e passa o resultado para a função do React executar. Isto se trata de um arranjo técnico.
No src/comum/hooks/use-aync.ts:
import { useEffect, useState } from "react"
interface AsyncReturnType<T> {
  isLoading: boolean;
  error: boolean;
  result: T | undefined;
}
export const useAsync = <T>(asyncFn: Promise<T>): AsyncReturnType => {
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState(false);
  const [result, setResult] = useState<T>();
  useEffect(() => {
    const foo = async () =>{
    setIsLoading(true);
    setError(false);
    try{
      const result = await asyncFn;
      setIsLoading(false);
      setResult(result);
    } catch (err) {
      setIsLoading(false);
      setError(true);
    }}
    foo();
  }, [setIsLoading, setResult, setError, asyncFn]);
  
  return {isLoading, error, result};
}
Aula 28 – Implementando o componente detalhe
Parte 01:
Agora iremos fazer o use-detalhe, nele é necessário o uso do useMemo() pois só queremos que o getByID seja chamado caso haja alguma mudança no tipo do controller ou caso o ID mude.
Utilizamos aqui também o use-async para carregar os dados.
A renderização é feita toda no detalhe, que pegará o valor passado para o fields e renderizará.
Aqui existe um detalhe a se notar, foi necessário trocar o tipo do ‘valor’ no FieldProps para ‘any’ pois no map do detalhe.tsx ele diz que o ‘value’ é desconhecido e por isso nao deixa compilar.
No detalhe.tsx:
import React from 'react';
import { SWAPIEndpoint } from '../../api/generic-api';
import { Button, CircularProgress, Grid } from '@material-ui/core';
import { getDetailData } from '../../api/controller-defs';
import { Field } from './field';
import { useDetalhe } from './use-detallhe';
import { People } from '../../api/schemas/people';
interface DetalheProps {
  id: number;
  controller: SWAPIEndpoint;
}
export const Detalhe = (props: DetalheProps) => {
  const { id, controller } = props;
  const { isLoading, result, error } = useDetalhe<People>(id, controller);
  const colunas = getDetailData(controller);
  if (isLoading)
    return (
      <div>
        <CircularProgress />
      </div>
    );
  if (!result) return null;
  return (
    <Grid container direction={'column'} spacing={2} alignItems={'stretch'}>
      <Grid>
        {Object.entries(result)
          .filter((item) => {
            const [key] = item;
            return colunas?.find((campo) => campo === key);
          })
          .map(item => {
            const [key, value] = item;
            return <Field nome={key} valor={value}/>;
          })}
      </Grid>
      <Grid>
        <Button variant={'outlined'}>Voltar</Button>
      </Grid>
    </Grid>
  );
};
No use-async.tsx:
import { useEffect, useState } from "react"
export interface AsyncReturnType<T> {
  isLoading: boolean;
  error: boolean;
  result: T | undefined;
}
export const useAsync = <T>(asyncFn: Promise<T>): AsyncReturnType<T> => {
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState(false);
  const [result, setResult] = useState<T>();
  useEffect(() => {
    const foo = async () =>{
    setIsLoading(true);
    setError(false);
    try{
      const result = await asyncFn;
      setIsLoading(false);
      setResult(result);
    } catch (err) {setIsLoading(false);
      setError(true);
    }}
    foo();
  }, [setIsLoading, setResult, setError, asyncFn]);
  
  return {isLoading, error, result};
}
No use-detalhe.tsx:
import { useMemo } from "react";
import { genericController, SWAPIEndpoint } from "../../api/generic-api";
import { AsyncReturnType, useAsync } from "../../comum/hooks/use-async";
export const useDetalhe = <T> (id:number, controllerName:SWAPIEndpoint):AsyncReturnType<T> => {
  const controller = useMemo(() => genericController<T>(controllerName).getByID(id),[controllerName, id]); 
  const {error, isLoading, result} = useAsync<T>(controller);
  return {error, isLoading, result};
}
Parte 02:
Aqui alteramos alguns parâmetros de tipo existentes no detalhe.tsx, no app.tsx e criamos um css básico para resetar o css do site.
html,
body {
  margin: 0;
  padding: 0;
  border: 0;
  box-sizing: border-box;
}
.centralizado {
  display: grid;
  place-items: center;
  width: 100vw;
  height: 100vh;
}
Aula 29 - Componente lista
Daqui para frente o professor parou de codar durante a aula, o código já vinha pronto para a aula, então ficaram apenas algumas anotações que achei interessante levar em conta.
Lembrando que todo o código está disponível em https://github.com/brigolini/StarWars 
useDebounce: é um módulo importado que permite atualizar alguma varíavel apenas depois de algum tempo. No caso ele utiliza esta função para atualizar a variável ‘search’ apensar depois de 500ms para que a aplicação não fique buscando por um resultado a cada caractere digitado pelo usuário. Isto garante que a API não fique senod acessada a cada caractere, o que dependendo da busca ou do usuário poderia levar ao impedimento do acesso da mesma.
Aula 30 - Roteando nossa app
O pacote que usamos responsável pelas rotas dentro da aplicação é o react-router-dom, ele é reponsável por enviar o usuário de uma página até a outra.
Para instalar basta fazer um yarn add ou npm install de react-router-dom. OU caso esteja mexendo com TS (que é o caso desta app) utilizar o add/install @types/react-router-dom; pois o pacote não vem tipado.
Aula 31 – Utilizando useHistory
Aqui todas as rotas já funcionam, agora implementasse o useHistory que ativa o botão responsável por navegar entre as páginas do item pesquisado.
O useHistory é um método importado que foi atribuído a uma variável ‘history’, ela é utilizada na função handleRowClick para levar o usuário para a página de detalhes do item selecionado.
Para isto o professor usa o useMemo para que o código de handleRowClick só seja executado quando a variável ‘history’ e/ou ‘controller’ for alterada.
O mesmo é feito utilizando para o botão voltar usando o handleVoltar através do ‘history,goBack()’
Então é criado o handlePageChange que é atribuído ao atributo onPageChange da tag DataGrid para que ao ter a página alterado essa alteração seja entendida pelo history para que possa voltar e ir de acordo.
Aula 32 – Terminando nossa App
Módulo 03
Aula 01 - Introdução e Preparação do Ambiente
Aqui instalamos a extensão no VSCode chamada angular language servisse e rodamos o comando npm install -g @angular/cli
Aula 02 - Arquitetura e Estrutura da Aplicação
Parte 01:
Criamos nossa primeira app em Angular utilizando o comando 
· ng new hello-world
Após baixar a internet um app é criado e pode ser criado um servidor de desenvolvimento através do comando 
· ng serve –open
Parte 02:
O app.component.html é o arquivo responsável pelo html da SPA.
Aula 03 - Componentes e Templates
O Angular é baseado em componentes e templates 
Parte 01 - Introdução à componentes e templates:
Todo component deve ter um jeito certo para ser nomeado, no exemplo a seguir criamos o arquivo c1.component.ts; o arquivo sempre terá seu nome, seguido de “.component.ts” para indicas ao Angular que é um componente e sempre na extensão TS pois o Angular é baseado em TS.
O componente também deve começar importando Component de @angular/core e exportando a classe que ele cria.
O componente deve fazer uso de um ou mais decorators que segundo a documentação:
Components are the most basic UI building block of an Angular app. An Angular app contains a tree of Angular components.
Angular components are a subset of directives, always associated with a template. Unlike other directives, only one component can be instantiated for a given element in a template.
A component must belong to an NgModule in order for it to be available to another component or application. To make it a member of an NgModule, list it in the declarations field of the NgModule metadata.
Após criar o componente ele deve se parecer com algo do tipo:
No c2.component.ts:
import { Component } from '@angular/core';
  @Component ({
    selector: 'c1', //como o componente será chamado por outro modulo como tag html
    templateUrl: './c1.component.html', //onde o template deste component está, o template é o que aparece na tela
  })
export class C1Component {
}
Então este componente deve ser incluído no módulo, para fazer isso no app.component.ts deve ser importado o componente recém criado.
No app.component.ts:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { C1Component } from './c1.component';
@NgModule({
  declarations: [
    AppComponent,
    C1Component
  ],
  imports: [
    BrowserModule,
    AppRoutingModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
Agora podemos usar a tag c1 no html do app
No app.component.ts:
Hello World!
<c1></c1>
E esta página deve mostrar:
Importante ressaltar aqui que todo componente montado usando o Angular é do tipo inLine a menos que esse comportamento seja alterado por estilo ou coisa do gênero.
Outra maneira de criar um componente é através do comando 
· ng generate component nome-do-componente-aqui
Esta é uma boa prática pois o comando ng já faz toda a organização do componente recém gerado para nós, criando o componente e todos seus arquivos relacionados dentro de um diretório, bem como já faz sua importação no app.component.ts.
Parte 02 - Data binding:
Data binding é uma característica do Angular que faz com que a interface reaja à mudanças de estados sem que haja a manipulação direta do DOM.
Para fazer isso vamos montar um exemplo de um componente utilizando seu respectivo comando “ng” para criar um counter.
No counter.component.ts:
import { Component, OnInit } from '@angular/core';
@Component({
  selector: 'app-counter',
  templateUrl: './counter.component.html',
  styleUrls: ['./counter.component.css']
})
export class CounterComponent {
  titulo: string = 'Contador';
  valor: number = 0
  increment() {
    this.valor++;
  }
}
Aqui criamos esse componente HTML através do Angular que pode ser adicionado apágina através da Tag <app-counter>, a ele atribuímos um atributo chamado titulo que é do tipo string e contém o valor ‘Contador’ e outro denominado ‘valor’ do tipo number que contém o valor 0. Ainda nesta classe, existe a função incremente() que adiciona 1 ao ‘this.value’ toda vez que é executada.
Para executar, adicionamos esta função a um botão no criado no template do componente.
Perceba que no código abaixo a sintaxe é um pouco diferente do que se faz em HTML puro, pois o angular permite isso.
No exemplo a seguir também usamos o propety binding, que é atrelar uma propriedade do DOM a uma propriedade do componente.
No counter.component.html:
<!-- Mostra o atributo dentro do {{}} no DOM -->
<p>Título: {{titulo}}</p> 
<p>Valor: {{valor}}</p> 
<!-- Faz o property binding desabilitando o botao quando o atributo 'valor' da classe for maior ou igual a 3 -->
<button [disabled]="valor >= 3" (click)="increment()">Increment!</button>
Aula 04 - Desafio Guiado 1
Parte 01:
Iniciamos criando o ap usando o ng new tic-tac-toe e então dentro deste novo projeto criamos um componente chamado também tic-tac-toe.

Continue navegando