O completo React Bootcamp 2023 (atualizado) | Arash Ahadzadeh | Skillshare
Pesquisar

Velocidade de reprodução


1.0x


  • 0.5x
  • 0.75x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 1.75x
  • 2x

O completo React Bootcamp 2023 (atualizado)

teacher avatar Arash Ahadzadeh, UI/UX Designer | University Lecturer

Assista a este curso e milhares de outros

Tenha acesso ilimitado a todos os cursos
Oferecidos por líderes do setor e profissionais do mercado
Os temas incluem ilustração, design, fotografia e muito mais

Assista a este curso e milhares de outros

Tenha acesso ilimitado a todos os cursos
Oferecidos por líderes do setor e profissionais do mercado
Os temas incluem ilustração, design, fotografia e muito mais

Aulas neste curso

    • 1.

      Introdução

      3:34

    • 2.

      Requisitos

      1:29

    • 3.

      Atualizações e problemas

      0:57

    • 4.

      Introdução à primeira seção

      0:14

    • 5.

      Como instalar Git + Git Bash (Windows)

      14:18

    • 6.

      Alterar a aparência do Git Bash (apenas Windows)

      3:46

    • 7.

      Instale o Git (macOS)

      1:09

    • 8.

      Como instalar o VSCode (Windows)

      3:27

    • 9.

      Instalar o código VS (macOS)

      0:42

    • 10.

      Configuração do VSCode e extensões

      9:50

    • 11.

      Como trabalhar com Git: parte 1

      12:52

    • 12.

      Como trabalhar com Git: parte 2

      10:58

    • 13.

      Como trabalhar com Git: parte 3

      12:54

    • 14.

      Como instalar o Node.js (Windows)

      4:44

    • 15.

      Como instalar o Node.js (macOS)

      1:08

    • 16.

      Node.js e NPM: parte 1

      9:38

    • 17.

      Node.js e NPM: parte 2

      14:39

    • 18.

      O que são mais bonitos e ESLint?

      20:04

    • 19.

      O que são Server, JSON, REST API e GraphQL?

      12:31

    • 20.

      Renderização do lado do cliente (SPA) VS. Renderização do lado do servidor (dinâmica e estática)

      13:06

    • 21.

      Atalhos de código do VS

      2:25

    • 22.

      Introdução ao JavaScript

      0:23

    • 23.

      Var VS. Deixe VS. Const

      9:26

    • 24.

      Para que é usado o Array.map?

      7:05

    • 25.

      Para que é usado o Array.redu?

      13:34

    • 26.

      Declaração de função VS. Expressão

      5:24

    • 27.

      Funções de seta e argumentos de função padrão

      10:01

    • 28.

      Interpolação de cadeias

      7:51

    • 29.

      Desestruturação de objetos e matrizes

      16:37

    • 30.

      Operadores de propagação e descanso

      13:07

    • 31.

      Código assíncrono, pilha de chamadas e loop de eventos

      20:01

    • 32.

      Código assíncrono e sincronização: promessas e assíncronos esperam

      21:09

    • 33.

      Módulos ECMAScript

      9:42

    • 34.

      ECMAScript ou JavaScript

      1:56

    • 35.

      O que é o React?

      2:46

    • 36.

      Abordagem baseada em componentes

      3:48

    • 37.

      Funções versus classes

      1:12

    • 38.

      Reaja sob o capô

      4:55

    • 39.

      Placas de caldeira e agrupamentos de projetos

      3:07

    • 40.

      Visão geral do projeto TicTacToe

      0:53

    • 41.

      Como criar e configurar novo projeto com o Vite

      24:11

    • 42.

      Extensões Eslint e Prettier

      1:45

    • 43.

      O que são componentes e adereços do React

      26:42

    • 44.

      Como aplicar estilos de CSS. Como configurar o SASS

      15:50

    • 45.

      React State com useGancho de estado, eventos React

      23:57

    • 46.

      Como criar estado do quadro de jogo

      21:12

    • 47.

      Adicione jogadores X e O

      7:09

    • 48.

      Mostrar mensagens ao próximo jogador e vencedor

      17:26

    • 49.

      Como mostrar o desenho do jogo

      20:13

    • 50.

      Como implementar o histórico de jogos

      35:25

    • 51.

      Como adicionar button de redefinição de jogos

      3:54

    • 52.

      Como destacar o vencedor do jogo (combinação vencedora)

      10:26

    • 53.

      Toque final. Como corrigir estilos, adicionar fonte, estilo inline

      8:19

    • 54.

      Implantação para aumentar

      9:53

    • 55.

      Resumo

      4:24

    • 56.

      Extra. Como adicionar grupos de fundo CSS.

      1:10

    • 57.

      Visão geral do aplicativo de bilheteira

      3:36

    • 58.

      Como criar o projeto com o aplicativo Create React

      23:31

    • 59.

      Como limpar arquivos redundantes

      5:31

    • 60.

      Introdução do React Router v6. Como criar páginas

      15:52

    • 61.

      Layouts e navegação entre páginas

      17:39

    • 62.

      Entradas. Encadernação de dados unidirecional e bidirecional

      9:53

    • 63.

      Envio de formulário. Como obter dados de programas da API TV Maze

      13:36

    • 64.

      Como renderizar dados de show da API TV Maze

      21:01

    • 65.

      Corrigir mais bonito não funciona

      3:38

    • 66.

      Botões de rádio. Adicione pesquisa para atores

      12:37

    • 67.

      Mover a lógica de formulários de pesquisa para seu próprio componente

      9:41

    • 68.

      Como exibir cartões para programas e atores

      25:04

    • 69.

      Páginas com conteúdo dinâmico. Como criar página de exibição

      11:21

    • 70.

      Introdução ao usoEfeito gancho

      16:06

    • 71.

      Como buscar dados da API da TV Maze com useEffect

      12:54

    • 72.

      Ganchos personalizados de reação. Como extrair e reutilizar a lógica de gancho

      6:58

    • 73.

      Como buscar dados com bibliotecas. Consulta de reagir

      13:32

    • 74.

      Tarefa. Reagir à consulta na página inicial

      2:01

    • 75.

      Como usar a consulta do React para pesquisar dados na página inicial

      9:01

    • 76.

      Como exibir informações na página Mostrar

      32:45

    • 77.

      Como adicionar o button Go Back na página Mostrar

      7:57

    • 78.

      Introdução ao useReducer como alternativa ao useState

      15:50

    • 79.

      Programas estrelados p1. Como criar estado com useReducer

      24:44

    • 80.

      Programas estrelados p2. Extrato estrelado mostra lógica em um gancho personalizado

      8:56

    • 81.

      Mostra estrelado p3. Buscar programas da API na página com estrela

      19:55

    • 82.

      Tarefa. Uso de gancho personalizadoPersistedState em cima de useState

      2:02

    • 83.

      Como implementar o uso de gancho personalizadoPersistedState

      7:40

    • 84.

      Introdução aos componentes estilizados. CSS-IN-JS como alternativa para estilo

      23:47

    • 85.

      Como criar estilo do aplicativo p1. Estilos globais, tema e link ativo do roteador React

      27:57

    • 86.

      Como criar estilo do aplicativo p2. Estilos dinâmicos de componentes com estilo baseados em acessórios

      26:39

    • 87.

      Como criar estilo do aplicativo p3. Animação FlexGrid e gancho de useRef

      15:15

    • 88.

      Implantação em páginas do Github

      17:06

    • 89.

      PWA (aplicativo web progressivo). Trabalhador de serviços

      19:01

    • 90.

      Como corrigir URL base para resolver corretamente imagens em páginas do Github

      5:38

    • 91.

      Toque final. Como criar favicons

      9:07

    • 92.

      Resumo. Conhecimento adquirido

      7:46

    • 93.

      O que é o Firebase?

      1:47

    • 94.

      Visão geral dos serviços do Firebase

      5:05

    • 95.

      Segurança do Firebase

      1:50

    • 96.

      Preços do Firebase

      1:02

    • 97.

      Visão geral do projeto

      8:47

    • 98.

      Atualizações do aplicativo de bate-papo estão chegando!!

      3:12

    • 99.

      Andaime do projeto

      7:55

    • 100.

      Crie e configure o projeto Firebase

      11:09

    • 101.

      Como criar páginas: rotas privadas e públicas

      7:56

    • 102.

      Página de entrada: interação com o Firebase

      21:24

    • 103.

      Como criar contexto de perfil: API de contexto e gerenciamento de estado global

      9:27

    • 104.

      Gerenciamento de estado de perfil global com contexto

      12:34

    • 105.

      Comece a criar a barra lateral e o painel

      7:43

    • 106.

      Barra lateral responsiva usando consulta de mídia

      3:16

    • 107.

      Como criar painel: parte 1

      5:42

    • 108.

      Como criar painel: componentes reutilizáveis e editáveis (parte 2)

      12:42

    • 109.

      Como criar painel: atualize o apelido do usuário (parte 3)

      4:10

    • 110.

      Como criar painel: conecte provedores de mídia social (parte 4)

      16:42

    • 111.

      Como criar painel: como criar avatar (parte 5)

      13:10

    • 112.

      Como criar painel: como enviar o avatar para o Firebase (parte 6)

      12:27

    • 113.

      Como criar painel: exibindo iniciais de avatar do usuário e nomes (parte 7)

      7:37

    • 114.

      Adicione butão da Create-Room e funcionalidade

      17:36

    • 115.

      Como criar listas de salas de bate-papo: parte 1

      8:49

    • 116.

      Como criar lista de salas de chat: contexto das salas (parte 2)

      5:47

    • 117.

      Como criar lista de salas de chat: mostre salas e use-as como links (parte 3)

      6:11

    • 118.

      Como criar layout aninhado para página inicial

      6:41

    • 119.

      Como criar layout/componente de página de bate-papo

      5:06

    • 120.

      Problema de API de contexto e uma solução potencial

      2:41

    • 121.

      Problema da API de contexto na prática: como criar o contexto atual da sala

      7:54

    • 122.

      Como criar bate-papo inicial: parte superior

      6:44

    • 123.

      Como desnormalizar dados: como criar parte inferior do bate-papo

      14:30

    • 124.

      Exibir a última mensagem na lista de quartos

      3:23

    • 125.

      Como trabalhar com dados desnormalizados

      10:21

    • 126.

      Como exibir mensagens de chat

      7:16

    • 127.

      Exibir dados do perfil do usuário

      4:53

    • 128.

      Como adicionar presença em tempo real: parte 1

      8:32

    • 129.

      Como adicionar presença em tempo real: parte 2

      7:42

    • 130.

      Como adicionar gaveta de edição da sala

      8:33

    • 131.

      Regras de acesso e segurança baseadas em funções

      9:56

    • 132.

      Gerenciamento de acesso baseado em funções

      8:43

    • 133.

      Como adicionar foco programático com ganchos

      2:50

    • 134.

      Como criar componente IconControl: gostos (parte 1)

      6:20

    • 135.

      Gosta de funcionalidade (parte 2)

      7:20

    • 136.

      Lidar com a operação de exclusão

      6:22

    • 137.

      Como adicionar o componente de upload: parte 1

      12:39

    • 138.

      Armazene arquivos enviados no banco de dados: parte 2

      4:16

    • 139.

      Exibir e baixar arquivos enviados: parte 3

      6:10

    • 140.

      Grave e envie mensagens de áudio: parte 4

      8:40

    • 141.

      Exibir áudio e excluir arquivo: parte 5

      4:50

    • 142.

      Feed de bate-papo em grupo por datas

      6:56

    • 143.

      Paginação e controle da posição rolada

      12:52

    • 144.

      Implantação na hospedagem do Firebase

      2:09

    • 145.

      Plano do projeto Firebase

      1:15

    • 146.

      O que são Serverless e contêineres?

      3:31

    • 147.

      Mensagens na nuvem: como tudo está conectado?

      1:28

    • 148.

      Como armazenar tokens de dispositivos no banco de dados

      8:06

    • 149.

      Como adicionar trabalhador de serviços

      3:17

    • 150.

      Configurar funções de nuvem e o Gerenciador de versões de nós (NVM)

      6:35

    • 151.

      Fluxo de notificações em nosso aplicativo: tipos de funções de nuvem

      1:56

    • 152.

      Como criar a função de nuvem FCM

      19:55

    • 153.

      Corrigir erros de função da nuvem

      1:15

    • 154.

      Como enviar e exibir notificações usando funções de nuvem

      15:01

    • 155.

      Como gerenciar usuários do FCM

      11:27

    • 156.

      Principais características do React

      0:28

    • 157.

      Portais do React

      4:41

    • 158.

      Limites do erro

      5:52

    • 159.

      Divisão de código

      4:40

    • 160.

      Conclusão

      0:34

    • 161.

      Resumo: conhecimento que você ganhou

      2:19

    • 162.

      Seus movimentos futuros

      3:54

  • --
  • Nível iniciante
  • Nível intermediário
  • Nível avançado
  • Todos os níveis

Gerado pela comunidade

O nível é determinado pela opinião da maioria dos estudantes que avaliaram este curso. Mostramos a recomendação do professor até que sejam coletadas as respostas de pelo menos 5 estudantes.

3.475

Estudantes

7

Projetos

Sobre este curso

Criado com versões atualizadas do React, React Hooks, Node.js, JavaScript e Firebase.

------

Do que é este curso?

Este curso é sobre o React: uma biblioteca que ajuda os desenvolvedores a criar interfaces de usuário na web. Mas o React não se limita apenas às interfaces de usuário, há muito mais nisso.

Você já se perguntou como os sites do Facebook, do Twitter ou da Netflix são criados e por que eles não se sentem como sites? React pode responder a tudo isso. Neste curso, mostramos como criar sites com a sensação de dispositivos móveis (aplicativos de página única), onde o React é a base.

Primeiro, vamos guiar você pelos fundamentos do desenvolvimento web antes de entrar no React. Aqui vamos falar sobre o JavaScript mais recente, Node.JS, Git, APIs e ferramentas essenciais para fazer você se sentir o mais confortável possível em qualquer etapa do processo de desenvolvimento.

Em seguida, passamos ligeiramente para Reagir com uma pequena porção da teoria. Neste ponto, você vai saber do que é feito o React e como ele funciona.

Nosso primeiro projeto é um jogo de tique-taque-dedo. Aqui você vai conhecer o básico, os ganchos e a funcionalidade principal do React. Ao final deste projeto, você será capaz de criar um aplicativo web simples que mostra seus fortes fundamentos do React. Aqui você vai experimentar o fluxo de desenvolvimento de um aplicativo React em geral.

O segundo projeto é um aplicativo de pesquisa de filmes chamado Box Office. Com este projeto, avançamos para casos de uso do React mais complexos e começamos a trabalhar com APIs externas, layout dinâmico e páginas combinados com diferentes abordagens para estilizar um aplicativo do React. Aqui vamos trabalhar com ganchos do React mais avançados e personalizados. Ao final deste projeto, vamos analisar e otimizar o aplicativo com gancho do React para torná-lo ainda mais rápido e confiável. Vamos até transformá-lo em um aplicativo web progressivo que funciona offline!

O projeto final será um aplicativo de bate-papo. Isso vai incluir as seguintes funcionalidades: logins de redes sociais, gerenciamento de contas, permissões baseadas em funções, dados em tempo real e muitos outros. Neste projeto, vamos combinar o React com o Firebase: uma solução de backend na nuvem, alimentada por banco de dados NoSQL. Você vai dominar o gerenciamento de estados global com a API de contexto e aprimorar seu conhecimento sobre ganchos do React. Na etapa final, vamos estender o aplicativo com back-end personalizado em forma de sem servidor.

Todos os nossos projetos terão uma interface de usuário amigável e bem projetada que é responsiva e otimizada para todos os dispositivos.

Este curso é exatamente o que você está buscando?

Se...

  • ... você está ansioso para aprender desenvolvimento de front-end com o React do zero...

  • ... você tem alguma experiência com o React, mas não se sente confiante...

  • ... você só começou a aprender desenvolvimento web e quer avançar em direção a ferramentas e tecnologias modernas.

  • ... você sente que ficou preso fazendo apenas HTML, CSS e alguns JS.

... então este curso é definitivamente para você!

O que você precisa para ter sucesso neste curso?

  • HTML e CSS são absolutamente necessários

  • Compreensão geral/básica de programação ou JavaScript

  • Sem experiência anterior com frameworks React ou JS

  • Paixão para aprender coisas novas :)

Após este curso, você terá:

  • Três projetos React do mundo real de diferentes complexidade que podem ser colocados em seu CV

  • Compreensão total do React

  • Experiência com bibliotecas populares do React

  • Conhecimento de como criar e implantar aplicativos do React

  • Conhecimento de backend sem servidor personalizado e do Firebase

Tópicos que serão abordados e explicados:

  • Noções básicas de reagir (sintaxe, conceitos fundamentais, teoria)

  • Modelos de andaimes (create-react-app, nano-react-app /w Parcel)

  • Estilo dos aplicativos React (CSS, SASS, biblioteca de componentes de UI, componentes com estilo CSS-IN-JS /w)

  • Renderização condicional (conteúdo e estilos dinâmicos)

  • Gerenciamento de estado, local + global (/w React Hooks, API de contexto)

  • Análise e otimização de componentes (/w gancho do React)

  • Gerenciamento de layout complexo

  • Páginas dinâmicas com o React Router

  • Aplicativos web progressivos e trabalhadores de serviços

  • Assinaturas em tempo real no React

  • Como usar APIs externas para buscar dados remotos

  • Implantação de aplicativos React

  • Backend sem servidor com funções de nuvem

  • JavaScript mais recente e moderno (ES6 - ES2020)

Não faz parte do React, mas incluiu:

  • Git, Node.js, APIs, ESLint e guias rápidos Prettier

  • Firebase (/w NoSQL banco de dados realtime, funções na nuvem, mensagens na nuvem, armazenamento em nuvem)

  • Ideia e conceito de cloud computing sem servidor + explicação sobre contêineres docker

E se você ficar preso durante o curso?

Ficar preso é pior e inevitável. Ao mesmo tempo, é uma coisa comum para um desenvolvedor. Entendemos isso e estamos sempre prontos para ajudar você com suas perguntas o mais rápido possível.

O que você está esperando? Comece o curso hoje!

A quem se destina este curso:

  • Qualquer pessoa que queira desenvolver aplicativos da web escaláveis com o React
  • Programadores que querem aumentar seu valor como desenvolvedores web
  • Pessoas que estão ansiosas para aprender como os aplicativos da web modernos estão funcionando e como tudo está conectado
  • Qualquer pessoa que queira desenvolver aplicativos como o Facebook ou o Twitter
  • Qualquer pessoa que queira se tornar um freelancer ou um desenvolvedor de aplicativos web independente

Conheça seu professor

Teacher Profile Image

Arash Ahadzadeh

UI/UX Designer | University Lecturer

Professor

I am a UI/UX Designer & an iOS developer with almost seven years of experience in application development and also ten years of graphic design and UI/UX design.
My passion is helping people to learn new skills in a short-term course and achieve their goals. I've been designing for over ten years and developing iOS apps for four years. It would be my honor if I could help you to learn to program in a simple word. I currently teach Figma, Sketch, Illustrator, Photoshop, Cinema 4D, HTML, CSS, JavaScript, etc.

Visualizar o perfil completo

Level: All Levels

Nota do curso

As expectativas foram atingidas?
    Superou!
  • 0%
  • Sim
  • 0%
  • Um pouco
  • 0%
  • Não
  • 0%

Por que fazer parte da Skillshare?

Faça cursos premiados Skillshare Original

Cada curso possui aulas curtas e projetos práticos

Sua assinatura apoia os professores da Skillshare

Aprenda em qualquer lugar

Faça cursos em qualquer lugar com o aplicativo da Skillshare. Assista no avião, no metrô ou em qualquer lugar que funcione melhor para você, por streaming ou download.

Transcrições

1. Introdução: Bem-vindo ao bootcamp de reação completo. Oi, meu nome é Andrew e sou o desenvolvedor do React. Oi, meu nome é nosso Ash e eu posso UI UX designer. Você já quis criar um aplicativo semelhante ao Twitter ou Facebook? Prefere praticar ao invés da teoria? Se sim, você está no lugar certo juntos, vamos construir três projetos separados de complexidade diferente do zero, um jogo tic-tac-toe e um aplicativo de pesquisa de filmes e, finalmente, uma conversa. Este curso é destinado a pessoas que estão ansiosas para desenvolver aplicativos web. Nós tecnologias que se tornam cada vez mais populares hoje em dia. Primeiro, discutiremos todos os conceitos básicos que você precisa saber antes de começar a reagir. Aqui vamos falar sobre nenhum GS, boas APIs de renderização do lado do cliente e do lado do servidor e ferramentas essenciais para que você se sinta confortável em qualquer fase das abordagens de desenvolvimento. Logo depois disso, temos uma seção dedicada de JavaScript, mas descobrimos os recursos mais recentes e atualizados do idioma. Então nos movemos ligeiramente para reagir com a pequena parte da teoria. Neste ponto, você vai conhecer uma vez que Riak é feito e como ele funciona. A partir daqui, começaremos com nosso primeiro projeto, aquele jogo de tic-tac-toe. Ele tem uma interface moderna com animações legais e funcionalidade perfeita neste projeto, conheça primeiro reagir. Você aprenderá a criar componentes, estilos dinâmicos em interfaces de usuário. Mas falaremos sobre gerenciamento estadual e eventos de ciclo de vida de componentes usando o Hooke. No final deste projeto, você será capaz de criar um aplicativo web simples que mostra o seu forte reagir básico, e você vai experimentar o fluxo de desenvolvimento em geral. O segundo projeto é chamado de bilheteria. Ele atua como um motor de busca para filmes e programas de TV. Você pode obter informações sobre qualquer filme ou AG. E além disso, você pode adicioná-los aos favoritos para revisá-los no futuro, nós esses projetos, você se move em direção a um aplicativo React mais complexo ou você está trabalhando com APIs externas e gerenciando cenários não primitivos usando ganchos 3i de traje. Além disso, você vai aprender sobre CSS e JS como uma alternativa para estilo e aplicação, vamos explorar o conceito de rotas dinâmicas e busca remota de dados. Você também entenderá como otimizar e analisar componentes Reagir usando ferramentas de reação integradas. No final desses projetos, vamos até transformar nosso aplicativo em um aplicativo web progressivo que funciona offline. Após a conclusão da bilheteria, você será capaz de criar um aplicativo típico React que requer conhecimento de reação mais abrangente e avançado. Nosso projeto final será um bate-papo com os recursos mais populares exigidos por qualquer aplicativo de bate-papo. Estes incluem logins de mídia social, gerenciamento de contas, permissões baseadas , dados em tempo real e muitos outros recursos legais neste projeto, você vai conhecer o Firebase em primeiro lugar. Aqui você dominará a autenticação do usuário e o gerenciamento de estado global. Nesta fase, reagir ganchos vai ser a sua principal arma para desenvolver um aplicativo React pronto para produção gerenciar estilos você mesmo nem sempre é desejável. É por isso que aqui vamos usar uma biblioteca de componentes de interface do usuário para utilizar um sistema de design pré-construído. Finalmente, desenvolveremos nosso próprio backend usando o Cloud Functions, e adicionaremos o recurso de notificações em tempo real ao nosso aplicativo de bate-papo. Espere, você não terminou. Você está pronto para ajudá-lo em qualquer fase do curso e responder suas perguntas o mais rápido possível. Você está pronto para explorar, reagir juntos. Vemo-nos na aula. 2. Requisitos: Oi, meu nome é Andrew. Serei seu instrutor. Jogue Dick Koers. Deixe-me falar sobre os requisitos para que este tribunal comece a trabalhar com reagir. Primeiro, todo o conhecimento sobre HTML e CSS é essencial. Eu não serei nenhuma atenção extra explicando o que é dif tag. O mesmo vale para CSS. Espero que você saiba sobre classes e seletores, mas não fará nenhuma parada para explicar básico de HTML e CSS. Mas você sempre pode fazer perguntas nos Comuns. Há definitivamente alguns momentos-chave fora HTML e CSS, e isso será explicado. Mas na maioria das vezes vamos trabalhar com JavaScript. Eu não espero que você seja um bom JavaScript ou tenha alguma experiência decente. Eu queria saber sobre programação em geral, você deve entender coisas básicas como o que está disponível ou uma guerra é um olhar de quatro. Você vai se levantar hoje. Sintaxe JavaScript. Durante o curso, é bastante amigável coração para entender. As partes serão explicadas, então não se preocupe com isso. Há também uma seção especial dedicada Onley ao JavaScript. Ele cobre aspectos mais importantes fora da língua para garantir que você sabe o suficiente para começar com corrida reagir, e eu tento fazer tudo o mais suave possível. Mas, no entanto, eu queria fazer tantas perguntas quanto você puder. E não seja tímido fazer perguntas tolas estavam sempre lá para te ajudar. Vamos resumir rapidamente. Você deve estar ciente de HTML CSS e algum conhecimento geral de programação. É isso. Vejo você no próximo vídeo. 3. Atualizações e problemas: Ei, neste vídeo, eu gostaria de fazer referência a um arquivo que irá informá-lo sobre as atualizações e mudanças que os seres humanos fazem durante o curso. Na web, tudo muda constantemente. E para acompanhar o conteúdo atualizado, criamos esse arquivo. Por favor, encontre atualizações e problemas arquivo pdf ponto na seção de projetos e recursos dentro de você verá dois capítulos principais, atualizações importantes e problemas comuns. Atualizações importantes afetam todos os que fazem o curso. Leia esse capítulo para evitar inconsistências durante os vídeos. Problemas comuns se referem a possíveis erros que você pode enfrentar e suas soluções junto. Consulte este arquivo em primeiro lugar quando você tiver algum problema. Na pior das hipóteses, leia o capítulo três. Queremos sempre mantê-lo atualizado. Somente. Boa sorte com os projetos. 4. Introdução à primeira seção: Ei, bem-vindo ao curso na seção Capa móvel Tudo o que precisamos saber antes de começar com o desenvolvimento de reagir. Isso inclui ferramentas, um pouco de teoria e algumas outras coisas. Espero que goste deles. Vemo-nos lá. 5. Instalando Git + Bash (Windows): Ei, neste vídeo vamos instalar e obter o que é bom e por que precisamos dele? Vamos cobrir tudo isso no próximo vídeo. Este vídeo é sobre instalação. Vamos. Como sempre, primeiro abrimos Google e depois procuraremos e obteremos isso nos levará ao site oficial. Em uma nova guia que vou abrir, não carrega. E na guia atual, vou procurar o Git instalado no local. Isso nos levará a pelo menos ume.com. Então, por que precisamos disso? Se você verá discrepâncias na instalação do Git ou se você estiver perdido sobre a instalação do Git. Este é o último tutorial de insolação atualizado e atualizado. Eu recomendo esse. Então, se você estiver no macOS, linux, Windows, isso não importa. Basta navegar aqui e é muito fácil e direto. Tudo bem, agora vamos voltar aos downloads. Este vídeo é direcionado para usuários do Windows, mas se você é do Linux ou do macOS, está totalmente bem também. Então, se você estiver no Linux, basta clicar aqui e, dependendo da sua distribuição, basta selecionar o comando. É muito fácil de fazer, ok? Se você vem do mundo macOS, você tem algumas opções. Você pode instalar adeus usando um gerenciador de pacotes como o Homebrew, ou você pode usar um instalador diretamente. Esse tutorial aqui, ele recomenda usar um instalador, que é a maneira mais fácil no macOS, ok? Como estamos no Windows, vamos clicar no Windows e obteremos o instalador. Novamente, se você estiver vindo de um sistema operacional diferente, ainda recomendo que você passe rapidamente este vídeo porque vamos abordar algumas questões importantes. Tudo bem, então abrimos o instalador e apertamos Next. O que precisamos aqui? Ícones adicionais. Isso depende de você, integração com o Windows Explorer. Portanto, esta é apenas a opção Windows. E queríamos selecionar o Git Bash aqui, e queríamos desmarcar uma boa GUI. Ninguém usa o bem para ir. Esta é uma ferramenta visual para representar um bom, certo? E o Git Bash é uma versão curta do terminal Unix chamada Bash. Portanto, esta versão curta está disponível no Windows no dia do Git Bash. E acho que isso é muito útil e conveniente. Então, no Windows, temos cmd e PowerShell, e vamos instalar o Git Bash e usá-lo em vez de CMD e PowerShell. Ok, então queríamos selecionar bom L de c. Então isso é apenas no caso de termos arquivos realmente grandes e nosso bom projeto, essa opção nos permitirá colocar esses arquivos. Então, em um bom projeto basicamente, então queríamos manter associações. Não preciso de atualizações diárias e perfil do Git Bash para o Windows Terminal. Portanto, não tenho certeza sobre este, mas acho que isso está relacionado ao novo Terminal Windows publicado recentemente. Ok, então eu também não quero isso. Então, em seguida, nesta etapa, vamos escolher um editor com o qual você se sinta confortável. Então eu sei que você ainda não sabe, mas, na verdade, existe a possibilidade de haver um conflito entre vários arquivos. E para resolver esse conflito, você terá que passar manualmente por esses arquivos e editá-los. Então, quando esse conflito ocorrer, o get abrirá um editor que você selecionar aqui por padrão. Ok, então escolha algo que você saiba como usar, por exemplo, o Visual Studio Code. Tudo bem, em seguida aqui. O que temos aqui, justificando, o nome da ramificação inicial em seu repositório também. Este é um complicado. Vamos selecionar, vamos selecionar, deixar, decidir. Mas o que se trata tudo isso. Bem, eu entendo, eu sei que você ainda não sabe, mas há esse conceito de ramificações em bom. Então, há cerca de um ano, boa comunidade e a comunidade do GitHub decidiram alterar o nome padrão do branch dois, principal logo antes de ser chamado de master. Agora é oficialmente chamado de principal, mas ainda há muitos projetos que continuam usando o master. Então, o que eu recomendo fazer é apenas escolher, selecionar, deixar, obter, decidir. Então, vamos clicar em Próximo. E aqui temos o ajuste do seu ambiente de caminho que desejamos selecionar a segunda opção Recomendada. Isso nos permitirá usar o Git de qualquer shell de terminal, seja CMD, PowerShell ou Bash, ou de qualquer outro software e shells que vamos instalar e usar. Então é por isso que a segunda opção é o que queremos. Nesta etapa. Não queremos mudar nada, basta manter um uso padrão que o OpenSSH empacotado receberá quatro. Suas conexões podem usar túneis SSH. Certo. É por isso que ele vem junto com o executável SSH, que vem do OpenSSH. Ok, em seguida, aqui, back-end de transporte https. Continue usando o OpenSSL. Não queremos mudá-lo também. Em seguida, aqui sobre terminações de linha. Bem, bom é uma ferramenta multiplataforma. No entanto, existem algumas coisas específicas que devem ser de alguma forma gerenciadas ou controladas para alcançar essa disponibilidade multiplataforma. E uma dessas coisas são finais de linha. O problema é que no Windows e em sistemas semelhantes ao UNIX, as terminações de linha têm codificações diferentes, ok? E isso pode criar grandes problemas para conseguir projetos. Portanto, isso nos dará a capacidade manter nosso projeto multiplataforma sem problemas. Isso é uma coisa muito pequena, mas é muito importante porque se você selecionar a terceira opção e se você fizer algumas alterações para obter o projeto no Windows e, em seguida, abrir esse projeto em um sistema operacional diferente, você terá muitos problemas. Por que não queremos isso. Então, para o Windows, selecionamos essa opção. Em seguida, configurou o Emulador de Terminal para usar com o Git Bash. Ok, então o Git Bash será novamente nosso novo shell que usaremos como alternativa ao CMD e ao PowerShell. Então minty é aquela janela do terminal, ok, então se eu abrir o CMD, eu tenho essa janela padrão do Windows, basicamente a direita, como diz, a segunda opção aqui, janela de console padrão. Então, mentee é que esse software, basicamente que executa o shell terminal trans, projeta dentro dele. Então, será aquela janela que poderemos configurar, mudar sua cor e codificação e outras coisas podem ser ligações de teclas, tudo isso. Então, isso é só que, você sabe, janela que executa projéteis terminais. Certo? Então, queremos usar o mentee e, em seguida, escolher o comportamento padrão da boa pesquisa. Você ainda não sabe disso, mas vamos escolher o padrão. Essa é a opção preferida, quase sempre. E eu diria sempre. Em seguida, escolha um auxiliar de credencial. Aqui queremos selecionar o núcleo do Git Credential Manager. Isso é específico para o Windows aqui, mas ainda usa essa opção. O que ele faz, haverá momentos, quero dizer, sempre assim. Queríamos hospedar nosso bom projeto em algum lugar. Nós hospedamos no GitHub. E para nos autorizar ao GitHub, teremos que inserir nossas credenciais para um GitHub, nosso nome de usuário e senha. Portanto, para não respondê-las sempre que essas credenciais devem ser armazenadas com segurança em algum lugar em um armazenamento em cache. No Windows, esse armazenamento em cache é chamado núcleo do Git Credential Manager. Então, é por isso que precisávamos não inserir nossas credenciais todas as vezes. Gostaríamos de enviar nossas alterações para o GitHub. Ok, em seguida, nesta etapa queríamos habilitar o armazenamento em cache do sistema, limpezas simbólicas. Mantenha-o como está. Nós batemos em seguida e não precisamos nenhum recurso experimental. Então, basta clicar em Instalar. Removendo a versão anterior. Sim, quero dizer, para mim porque eu já o tinha instalado. Vamos esperar um segundo até que ele seja instalado e vamos ver o que temos. Certo, bom. Concluindo o assistente de boa configuração. Não quero que as notas de versão terminem. Agora, o bom está instalado. Como podemos verificar isso? Vamos para o CMD. E no cmd, queremos apenas digitar git space dash, dash version. E se você vir a versão instalada, parabéns, o get agora está instalado. Agora, isso está relacionado apenas aos usuários do Windows que instalaram, que selecionaram o Git Bash durante a instalação. Como podemos verificar manter o Bash? Bem, podemos executar git Bash diretamente de outro shell, de ver o Cmd, por exemplo. Então, se eu digitar Git Bash com traço dentro, verei que o Git Bash não é reconhecido. Bem, isso é para ser honesto, esperado. E para corrigir isso, temos que fazer novamente, uma pequena mudança em nossa variável de caminho. Então, o que precisamos fazer é iniciar o Painel e em busca com Tipo III e V. Em seguida, vamos editar as variáveis de ambiente do sistema e vegetais vitamínicos. E, em Sistema, as bolhas procurarão o caminho. Clique duas vezes sobre isso. E aqui no final da lista você verá Arquivos de Programas C, bom, CMD ou qualquer caminho de instalação que você escolheu durante a instalação. Ok, então se abrirmos esse caminho, vamos para pastas. E vamos aqui. executáveis que temos aqui são bons, bons GUI, tudo menos exceto o Git Bash. No entanto, se formos para obter a pasta aqui, temos o executável do Git Bash. Tudo bem? Portanto, para usar esse executável a partir do terminal, temos que adicionar o caminho da pasta à variável de caminho. Certo? Então voltamos aqui para essa lista. Clicamos em Novo e adicionamos Arquivos de Programas C. Bom. Então nós batemos OK, OK, OK. Agora vou reiniciar o terminal novamente. E agora, se eu digitar Git Bash, boom, estou dentro do shell do Git Bash e ele usa minty. Então, se eu clicar nas opções aqui, você verá esse logotipo de menta. Portanto, pode parecer muito parecido, mas na verdade usa como o console padrão do Windows. Mas isso é executado dentro do minty Terminal Emulator. Tudo bem, se você quiser, você pode configurar diferentes opções aqui, Seleção de chaves, Terminal do Windows. Então, essas são todas as opções e apenas precaução, e este é o Git Bash. Agora, se quisermos digitar comandos Linux muito básicos aqui, podemos fazer isso, por exemplo, ls, para listar todos os arquivos nesta pasta. Ok, ótimo, e esta é a nossa entropia dos usuários C. Isso é meu. Será seu nome de usuário aqui. Se quiséssemos ir para um disco diferente, vamos digitar cd para alterar o diretório e, em seguida, o nome do disco. Ótimo, então isso é sobre o Git Bash. Você também pode executá-lo a partir da janela de execução no Painel Iniciar ou pressionando Windows plus r e digitando Git Bash. E você está lá dentro. Isso é basicamente, é, isso é tudo o que precisamos para configurar o Git, ok, Talvez mais uma opção seja o comando Git config, certo? Então, se formos a isso na lesão ao total, não importa quando para Windows, para Linux não importa. Então aqui precisamos configurar, usar nosso nome e e-mail, certo? Então, basta copiar esse comando aqui e colá-lo no terminal. E aqui insira seu nome. Pode ser o seu nome verdadeiro, ou pode ser o seu apelido, o que quer que você faça. Então pressione Enter para seu nome de usuário e, em seguida, o mesmo para e-mail. Então, o que são esses? Eles ficarão visíveis nas mensagens de commit. Na boa história, abordaremos tudo isso, mas isso é algo que outros usuários e você verão no histórico do seu projeto, escolherão algo real, que é basicamente ele é instalado para Usuário do Windows, você obtém bashes instalados. No próximo vídeo, falaremos sobre isso em detalhes e como isso facilitará nossas vidas. Vejo você lá. 6. Altere o bucha de Git (somente Windows): Ei, antes de tudo, quero mencionar que este vídeo é apenas para usuários do Windows. Neste vídeo, gostaria de abordar a aparência do Git Bash. Deixe-me mostrar o que quero dizer. Se eu iniciar o Git Bash. Não gosto do jeito que parece. Quero remover isso significa W 64, quero remover essa entrada B em, no nome da minha máquina. Não preciso de tudo isso. Isso é totalmente opcional, mas tornará a experiência do desenvolvedor um pouco mais agradável. Então, vamos mudar isso. O que temos que fazer, temos que navegar para obter a pasta de instalação no início. Então, para mim, vai ser C, Arquivos de Programas, bom. Dentro desta pasta, queremos ETC. E o perfil D aqui procurará um bom ponto prompt SH, e nós o abrimos com qualquer editor de texto. Vou abri-lo com o Sublime Text. E você verá isso. Sei o que vai ser completamente confuso e não sabemos o que está acontecendo aqui, mas não entre em pânico. Só queremos removê-los ou talvez substituí-los por outra coisa. Então, antes de tudo, para remover esse título Ming W6 vamos procurar algo com título, aparentemente. Portanto, esse prefixo de título de cifrão é exatamente para Ming W 64. Então, acabamos de removê-lo daqui. E também removemos os dois pontos, mas não removemos esse ponto e vírgula daqui porque isso faz parte dessa cor representada como esta basicamente. Então aqui, deixe-me colocar meu apelido com uma seta e deixe-me salvar o arquivo. Agora, deixe-me reiniciar o Git Bash. Então, novamente, vou para a janela Executar Git Bash. E agora boom, eu vejo meu apelido e, e eu faço muito legal agora eu quero remover tudo o que destaquei. Então eu procuro o sistema EMS. Acabei de remover essa linha completamente. Em seguida, removo o usuário no nome do host. E também o que eu gostaria de fazer, gostaria de destacar o caminho atual, que é exibido aqui. Então, se eu navegar para ver, eu tenho assim, mas eu queria colocá-lo entre parênteses. Então, a barra invertida w é o diretório de trabalho atual. Então eu quero colocá-lo dentro de suportes de caixa assim. Tudo bem, e uma aula, o que eu queria fazer, eu queria mudar o prompt do cifrão para uma flecha talvez. Então aqui eu procuro esta linha. Tudo bem, prompt será sempre uma seta. Eu mudo, salvei o arquivo e agora vamos ver o resultado. Então, novamente, reinicio o Git Bash. E agora esta é a nossa aparição final. Se navegarmos para o disco D, nós o teremos assim. Muito legal. Então, novamente, isso é totalmente opcional e essa é minha preferência pessoal porque eu gosto da simplicidade e gosto da aparência. E para mim, do meu ponto de vista, parece muito, muito melhor do que era antes. Depende totalmente de você se você precisava ou não. Mas é isso. Isso é o que eu queria abordar. Vejo você no próximo. 7. Instale o Git (macOS): Ei, neste vídeo, vou mostrar como instalar o Git no Mac OS. Primeiro, navegue até o Google e digite git. Vá para o primeiro URL. Este é o site oficial. Clique em downloads e selecione macOS. Você verá algumas maneiras de instalar o Git. Vamos escolher aquele com Homebrew. Homebrew é um gerenciador de pacotes. Ele nos permite baixar software distribuído com um único comando de terminal. Instale o Homebrew, copie o comando de instalação do site, vá para o Launchpad e execute o terminal, cole o comando e aguarde que ele seja instalado. Ele também pode solicitar sua senha. Agora que temos Homebrew, podemos instalar facilmente o Git, navegar de volta para obter o site e copiar homebrew instalado Git, abrir o terminal e colar o comando. Levará alguns segundos até que a homebrew seja instalada entre em seu sistema. Se diz que o get já está instalado, então você está bem. Provavelmente é por causa do Xcode. E é isso. Tchau. 8. Instalando VSCOde (Windows): Olá, Neste vídeo, instalaremos o VS Code e editor que usaremos durante todo o curso. Primeiro de tudo, por que o código VS Code ou Visual Studio? Acho que pessoalmente acho que este é um dos melhores editores e IDE disponíveis para projetos JavaScript. Se você estiver confortável com qualquer outro editor, por exemplo, átomo para desenvolvimento, se você tiver alguma experiência anterior, sinta-se à vontade para usá-lo. Mas em treinamento, eu aconselho seu pseudocódigo de mísseis devido ao seu sistema plug-in e é apenas confortável. Ok, então vamos instalá-lo. O que temos que fazer é ir ao Google como sempre e digitar VS Code. E isso nos leva ao site oficial. Então eu sugiro abrir a página de documentos e não procurar a página. Então, na página de download, temos instaladores para três sistemas operacionais diferentes, Windows, Linux e macOS. Então, para o Windows, é bem direto, certo? Você clica no instalador e ele inicia o download, ok, para Linux e macOS, eu aconselho ir para a página de documentos e, em seguida, dependendo do seu sistema operacional, vá para a seção apropriada. Então, para o Linux, também é bem simples. Dependendo da sua distribuição Linux, há cães que você pode ler e ver como você precisa instalar o NodeJS. Quero dizer, como exatamente você vai fazer isso porque os comandos serão diferentes com base na sua distribuição. Certo, então apenas trate os cães. Confie em mim, isso é bem simples e basicamente o mesmo para Mac OS. Essa é uma maneira fácil. Você obtém o instalador e simplesmente arrasta-o para o seu launchpad. É isso. E o VS Code é considerado instalado. Ok, então, para o Windows, temos o instalador. Vamos lançá-lo. Este usuário pretendia correr para nos aterrar e disse: Oh, pague. Então, sim, quero continuar correndo. Certo. Eu fecho isso. Você não verá isso. Certo. Então, estou aqui. Fui aceitar. Você pode alterar o caminho se quiser isso como instalação padrão. Isso também está escrito em cães. Você pode ler sobre isso aqui. Então, onde está? Certo, está aqui. Agora clicamos em Avançar. Em seguida. Agora, aqui precisamos selecionar dois caminhos selecionados por padrão, mas certifique-se de que ele esteja lá. Registre o código como um aditivo para tipos de arquivos de suporte. Sim, é aconselhável que seja selecionado. Isso é opcional e, se você precisar criar o item da área de trabalho, ok, clique em Instalar. Depois disso, levará algum tempo e boom, você verá o código VS em sua área de trabalho. Depois disso, você o inicia e você acaba em uma janela como essa, o tema será diferente, mas não importa. Vscode agora está instalado. Como configurar com código SQL e como instalar plugins. Tudo será abordado no próximo vídeo. Vejo você lá. 9. Instale o código VS (macOS ): Olá, Neste vídeo, mostrarei como instalar o código VS no macOS, ir para a pesquisa do Google e digitar fiasco, depois clicar no botão Download e ele o levará para a página de download. Clique no instalador do macOS. Ele iniciará automaticamente o download para você, aguarde até que esteja pronto. E isso abriu o arquivo dentro, você verá o código VS. Eu posso atalho, basta arrastar e soltar o ícone nos aplicativos logo depois disso, VS Code é considerado instalado e você pode acessá-lo indo para o almoço, mas depois procure o VS Code, abra e verifique se está tudo bem. E isso é tudo. Veja no próximo. 10. Configuração de VSCode e extensões: Ei, neste vídeo, gostaria de falar sobre o código VS, como configuramos o VS Code e o que precisamos fazer para sentirmos confortáveis durante o desenvolvimento. Vamos. A primeira coisa que eu gostaria de apresentar é a barra de pesquisa de código VS, porque é incrível abrir a barra de pesquisa. Eu pressiono Control P. E isso me traz aqui. Posso digitar qualquer coisa que eu quiser aqui, mas não dará resultados correspondentes porque ele tenta procurar defiles no projeto atual. Mas como não temos nenhum projeto no momento em que abri, ele não dá resultados correspondentes. O que eu quero digitar é a seta para a direita. Digitando a seta para a direita no início. Isso significa que eu quero usar comandos internos do VS Code ou opções de código VS talvez para navegar sombrio. Por exemplo, se eu digitar seta e, em seguida, configurações JSON, isso me dará preferências em aberto configurações castigadas. Deixe-me clicar nesse e isso me leva às configurações do arquivo JSON. Portanto, o arquivo JSON de configurações é basicamente como arquivo de configuração do usuário de código. Aqui só precisamos digitar comandos diferentes para configurar extensões, configurar algumas ferramentas ou o que quer que seja. A primeira coisa que eu queria colocar aqui, deixe-me abrir o navegador. E aqui eu tenho esse arquivo, essa configuração de código. Você terá esse URL e talvez já como ele é compartilhado. Então, basta abri-lo. E a partir daqui, a primeira coisa vou pegar a janela de confiança de segurança do IS. E vou colocá-lo aqui assim. E o que ele faz, ele desativa a janela de segurança, mas não entre em pânico. O que é janela de segurança? Bem, o código VS perguntará muitas vezes, você confia nesse ambiente ou confia nessa pasta? E confie em mim, isso é muito chato desativar essa janela. Basta copiar colar esta opção e você nunca verá essa janela. Mais uma vez. Se você estiver curioso, você sempre pode comentar essa linha de código e vê-la você mesmo. Mas vou mantê-lo como está. Agora, por um segundo. Vou deixar a segunda opção e vou pegar a última opção daqui, que é sobre pregador. O que é pregador? Pre-clear é uma ferramenta que abordaremos em detalhes no próximo vídeo. Preacher formará nosso código quando salvarmos arquivos, linha garante que quando clicarmos em salvar, nosso código será formatado. Nesta etapa, o VS Code basicamente já está configurado e você pode iniciar tentativas de desenvolvimento imediatamente. Mas uma coisa que quero mencionar é o terminal integrado VScode. Então, se eu pressionar o terminal e clicar em novo terminal, ele abrirá o PowerShell para mim porque estou no Windows. Se você estiver no Linux ou no macOS, verá Bash para usuários Linux e macOS, tudo bem. Mas para usuários do Windows, desde que instalamos o Git Bash, vamos usar o Git Bash e não o PowerShell ou Cmd porque, por padrão, o VS Code e o Windows usam o PowerShell. Então, o que precisamos fazer? Precisamos voltar para esse arquivo e copiar essa configuração e deixe-me colocá-lo aqui no final. Então, o que ele fará, instruirá o VSCode a usar o Git Bash como terminal integrado. Não é diferente, como se você o abriria fora do VSCode. É conveniente usar tudo em um só lugar, especialmente ferramenta como terminal. Copiei todas essas opções se o caminho for diferente para você, basta substituí-lo seguindo o mesmo padrão. E vamos fechá-lo e depois vamos abri-lo novamente. E vamos verificar se agora estamos usando o Git Bash. Dito isso, os usuários do Windows parabéns, estamos usando o Git Bash. Agora, a última coisa que eu quero falar neste vídeo, e eu diria que a mais importante é as extensões VS Code. Tudo bem? Então, o que são extensões VS Code? Essas são ferramentas opcionais que ampliam VS Code com uma ótima funcionalidade. Para ir para Extensões, clicamos neste ícone no painel esquerdo. E aqui eu já tenho 33 extensões instaladas. É muito que eu sei, mas não entre em pânico. Não precisamos instalar todos eles. O que vou fazer agora, vou passar rapidamente pelas extensões que acho necessárias para o nosso curso. E caberá a você se você deseja instalá-los ou não. Para vender e ampliar na barra de pesquisa, basta digitar o nome da extensão. Por exemplo, melhor sintaxe C Plus Plus. Você clica na extensão, por exemplo, nessa e pressiona Instalar. Depois disso, ele será instalado. E pode pedir que você reinicie o código VS, mas é muito raro. E, a propósito, não preciso dessa extensão, então vou desinstalá-la. Então volto para Extensões Instaladas e vamos procurá-las rapidamente. A primeira extensão que eu quero mencionar está disponível para a tag de nome. O que ele fará. Ele será apenas renomeado HTML, abrindo e fechando a tag à medida que digitamos HTML. Isso é muito útil. Eu recomendo este, riser de cor de pêra de suporte. Eu acho que essa é uma das extensões que deve instalar porque simplesmente destaca abertura e fechamento do colchete e decodificação. Isso é útil porque torna nosso código mais legível e distinguível. Eu recomendo esta extensão. Em seguida, temos snippets ES 7 React redux GraphQL React Native. Esta é uma extensão importante. Vamos utilizá-lo muito quando vamos escrever código React. Então instale-o. Vou mencionar essa extensão no futuro mais uma vez. Então temos ES fiapos. Vamos cobrir o ES lint em mais detalhes no próximo vídeo. Mas certifique-se de ter essa extensão instalada antecipadamente. Em seguida, temos a tag de correspondência de destaque. Assim como diz, ele destacará a tag HTML correspondente, assim como você vê nisso. Pré-visualização. Muito legal. Acho que é, é, é útil. Agora temos o IntelliSense para nomes de classes CSS. Bem, sim, é útil. Então, o que ele fará, ele adicionará preenchimento automático para nomes de classes CSS definidos em nosso projeto, totalmente com você. Em seguida, temos Material Icon Theme. Ele apenas adicionará esse conjunto de ícones aos arquivos que veremos no Explorador de Arquivos aqui no painel esquerdo. Eu uso e recomendo a todos. Inteligência Npm. Este é importante. O que ele fará, adicionará preenchimento externo para pacotes e bibliotecas que vamos importar para código, altamente recomendado. Em seguida, temos inteligência de caminho. Basicamente a mesma coisa, mas para arquivos locais. Portanto, preenchimento automático para importação de arquivos locais. Então temos pregador, pregadores, uma ferramenta que formatará nossos arquivos. Então, novamente, vamos cobrir isso em detalhes, então apenas certifique-se de que ele está instalado. E a última extensão será alternada por aspas. cotação de alternância é muito simples. Basicamente, apenas alterna as citações. Por exemplo, se for lido aqui, precisamos pressionar isso dependendo do seu sistema operacional para alternar aspas de simples para duplo, de duplo para backticks. Deixe-me demonstrar para você. Se você apenas pressionar esses botões em qualquer lugar, você terá Esta mensagem informando que a execução do Comando contribuído falhou. O problema é que você precisa usar esse comando somente dentro de aspas. Tenho que colocar meu cursor aqui dentro de um texto com aspas e depois usar a combinação para triplicar aspas. Eu uso muito pessoalmente e recomendo a todos. Acho que é isso. Eu cobri tudo o que eu queria. Mencionei todas as extensões que acho importantes. Eu lhe dei tudo sobre configurações, JSON, você sabe, sobre terminal integrado. Eu pessoalmente abro com controle mais ligação de chave J, não daqui. E sim, é isso. Talvez mais uma coisa a mencionar seja o tema VSCode. Se você quiser que o VS Code pareça legal, procure um tema de extensão, ok, e escolha algo que você gosta. Eu pessoalmente gosto do tema Firefox. E eu já o tenho instalado. Então, vou clicar em Set Color Theme, Firefox, dark e boom. Agora tenho cores diferentes no meu código VS. Muito bom. Ele também tem um tema leve se você estiver interessado. Certo, acho que é tudo. Vejo você no próximo. 11. Trabalhando com Git - Parte 1: Ei, neste vídeo, vamos falar sobre, bom, vamos. Primeiro de tudo, o que é o Git? O Git é uma ferramenta de gerenciamento de projetos que nos permitirá acompanhar todos os nossos arquivos de projeto. Por exemplo, faremos muitas alterações nosso código-fonte quando vamos desenvolver nossos projetos. Talvez leve um ano. Talvez demore dois anos para desenvolver esse projeto. Depois de um ano, provavelmente não me lembrarei do que fiz no passado, como o medo atrás. E para ter esse histórico de projeto, o Bom existe. Isso nos permitirá ver quais mudanças fizemos, o que exatamente deu errado nesta etapa específica. Talvez gostássemos de mudar alguma coisa. Talvez gostaríamos de contribuir com outras pessoas e, para gerenciar tudo isso, o bem existe. Agora, vamos ver tudo isso na prática. Primeiro, criarei uma nova pasta de projeto. Já abro o VS Code. Agora precisamos abrir uma pasta de projeto. Vou clicar em File Open Folder. Em seguida, vou navegar até uma pasta onde quero criar outra pasta. Este será meu projeto de teste, e eu o abrirei no VS Code. Ótimo. Agora vamos abrir o terminal integrado. Vou pressionar Control mais j. E ele abrirá o Git Bash para mim. E, como você pode ver, ele já está na pasta do projeto. Ótimo. Agora, precisamos inicializar bem nesta pasta do projeto primeiro. Para fazer isso, precisamos digitar git nele. E você verá essa mensagem inicializada repositório git vazio nesta pasta. E ponto importante aqui que ele criará um ponto de pasta oculta obter uma ordem para visualizar essa pasta oculta, precisamos digitar ls menos a. Ele mostrará todos os arquivos e pastas na pasta atual mais pastas ocultas. Tão bom. E podemos realmente navegar para essa pasta usando cd para alterar o diretório. E então podemos digitar ls novamente para visualizar todos os arquivos e pastas. E você pode ver um monte de coisas aqui, mas não estamos interessados nelas. Ponto importante aqui que, se vamos excluir esta pasta, todos os nossos bons detalhes do projeto serão excluídos. Então, se eu navegar de volta para a pasta principal, usarei CD e dois pontos, e agora vou excluí-lo. Então, vou digitar uma RAM do que nosso F e nome da pasta para excluir todos os arquivos e pastas dentro do bem, e obter a própria pasta. Agora você pode ver esse título mestre e mestre desapareceu aqui. Isso significa que agora o get é totalmente excluído desta pasta. Agora deixe-me digitar git nele novamente. E boom, bom, agora é inicializado mais uma vez. Ótimo. Agora, e esse título mestre aqui? O que é isso? Este é o nosso ramo atual. Vamos falar sobre filiais mais tarde. Agora mesmo. Não se concentre nisso. Estamos interessados em obter o que ele faz. Então, quais são os benefícios? Primeiro, vamos criar um arquivo aqui. Vamos chamá-lo de algum ponto de arquivo TXT. Aqui vamos digitar olá. Talvez este seja o nosso arquivo principal do projeto, muito despejo, mas fará o truque. Agora, para usar o bem, podemos digitar git status em primeiro lugar para entender o que está acontecendo neste momento específico em um bom projeto. Então você ainda não pode ver commits. Atualmente, estamos no branch master e temos vários arquivos não rastreados para serem mais específicos. Para um arquivo, alguns file.txt, nada adicionado ao commit, mas arquivos não rastreados presentes em um bom projeto arquivos podem estar em três estados diferentes. primeiro estado é um estado não rastreado, segundo estado é o estado do estágio. terceiro estado é quando os arquivos são confirmados. Então, neste momento, estamos em estado não rastreado. O que isso significa? Isso significa que seja detectado que temos alguns novos arquivos em nosso projeto, mas eles ainda não fazem parte desse bom projeto. Para adicionar esses arquivos, para que eles saibam que queremos rastrear esses arquivos para incluí-los como parte de nosso bom projeto, precisamos adicioná-los ao estado do palco. Para fazer isso, precisamos digitar exatamente como diz aqui, git add file. Então, podemos digitar git, adicionar um pouco de file.txt. Pressionei tab para preenchimento automático. Então eu apenas digito algum arquivo, algum F, depois pressione Tab e ele permitirá completar o nome do arquivo para mim. Mas também posso fazer git add dot para adicionar todos os arquivos nesta pasta ao estado do palco. Portanto, o ponto representa todos os arquivos no diretório atual. Vou usar esse comando porque ele é mais curto. Git add dot. Agora você pode ver a cor alterada para azul aqui. E o que está acontecendo. Vamos digitar git status novamente para ver o que ainda não temos commits, alterações a serem confirmadas. Agora você pode ver que temos um novo arquivo, alguns file.txt. Ótimo. Isso significa que nosso arquivo está no estado do palco. E como estamos usando o VS Code, VS Code tem integração com o Git e a desintegração é uma ferramenta realmente poderosa. É por isso que aqui no painel esquerdo temos esse ícone com um número dentro dele. Vamos clicar nisso. Portanto, essas guias representam obter integração. Assim, você pode ver que temos dois suspensos aqui, mudanças e alterações preparadas. Você pode ver que agora nossa soma file.txt dentro das alterações preparadas. Então você pode ver à esquerda o que era antes, e à direita com verde, o que foi adicionado, já que é um novo arquivo, não vemos nada e vermelho à esquerda. Agora, se você está lutando com todos esses bons comandos ou eu não sei Por algum motivo, é difícil para você se lembrar de todos eles. Você sempre pode usar a integração com o Git aqui. Então, se eu clicar em menos aqui, ele excluirá esse arquivo do estado do palco e ele o reverterá de volta para o estado não rastreado. Agora, se eu digitar git status, o terminal novamente, você pode ver arquivos não rastreados, alguns file.txt. Agora, se eu quiser adicionar esse arquivo ao estado do palco, basta clicar no sinal de mais. Boom, é, está em encenado novamente. Ótimo. Agora, qual é o estado do palco? Bem, esse estado de estágio é basicamente aquele estágio pré-operacional em que os arquivos podem ser confirmados. Então, o que é um commit? Um commit é apenas um registro no histórico do Git e representa as alterações feitas no projeto. Agora vamos confirmar esse arquivo em nosso bom histórico. Então, o que podemos fazer, podemos digitar git commit e , em seguida, precisamos digitar menos M para mensagem de commit. E vamos digitar alguns file.txt adicionados. Vou executar esse comando. E você verá o modo tratado, um arquivo alterado, uma inserção, ótimo. E todas as mudanças à esquerda desapareceram. Tudo bem. Agora, se vamos digitar git status novamente, você não verá nada para confirmar. Isso ocorre porque o commit é arma. Já está no passado. Good acompanha todos os nossos commits que fizemos no passado. Para visualizar o histórico do Git e o terminal, temos que digitar git log. Temos um commit que nomeamos edit some file.txt. Data é este e o autor, meu apelido e meu e-mail e commit hash no branch master. Digamos que eu queira adicionar novas alterações a esse arquivo. Vou apenas ir em frente e modificar esse arquivo. Vou digitar algo despejado e salvar o arquivo. À esquerda, você verá que temos novamente novas alterações no arquivo. E isso é o que adicionamos, isso é o que tínhamos antes. Agora, os mesmos passos. Precisamos primeiro adicionar essas alterações ou aquele arquivo que foi alterado para o estado do palco, certo? E depois disso, poderemos confirmar esse arquivo. Porque agora, se eu vou fazer git commit e digitar algo, você verá uma mensagem de erro. Bem, não é uma mensagem de erro, mas não confirmará nada porque bom só pode confirmar arquivos preparados. Por exemplo, se eu vou criar um novo arquivo, test.js e vou digitar, não sei, coisa muito básica em JavaScript, log do console. Olá. Vou voltar para essa guia. Vou digitar git status. Você verá que um arquivo foi modificado, um arquivo não é rastreado. Agora eu quero encenar todos esses arquivos. Vou fazer git add dot. E você verá que todos eles estão agora encenados. E se eu for digitar git commit, esses arquivos preparados serão adicionados ao novo commit. Tudo bem? No entanto, e se eu não quiser que todos esses arquivos sejam confirmados? Talvez eu tenha criado esse arquivo, mas ainda não estou pronto para confirmá-lo. Eu só quero comprometer essas mudanças no histórico. Então, o que vou fazer, removerei test.js desse estado de estágio e deixarei apenas algum arquivo nesse estágio. Então, como eu disse antes, git confirma apenas arquivos preparados. Então, se eu for digitar git commit e vou digitar algum file.txt editado. Vou executá-lo. Você verá que o teste permanece porque ele ainda não está rastreado, não confirmado. E se eu digitar git log, verei agora que tenho que confirmar a nota. Agora, se eu quiser adicionar test.js, vou digitar novamente git add dot e depois git commit. E vou digitar edit, test. Sim, legal. Mais uma vez, boa sorte. E eu tenho meu histórico do Git lá. Isso é o que o bem faz. Ele nos permite criar esse histórico do projeto por meio de mensagens de commit. Mas, ok, isso parece útil, mas não vejo o ponto principal aqui para ver todos os arquivos, todas as alterações que você fez para obter projetos ou comandos diferentes, como um bom show, por exemplo. Assim, podemos digitar git show e, em seguida, commit hash para visualizar as alterações feitas neste commit específico. Então, vou apenas copiar isso e colocar uma boa mensagem de dinheiro do show. Temos esse commit. Essa é a diferença. No arquivo. Alguns file.txt, temos uma linha editada e a segunda linha editada. É isso. Então agora eu concordei que isso não é conveniente ver tudo através do terminal. É por isso que existem muitas extensões VS Code que podemos instalar para visualizar esse processo. Então, se eu digitar git na pesquisa de extensão, você verá muitas extensões diferentes como bom histórico, obter terras, bom gráfico. E todos eles ajudarão você a trabalhar com o bem. Eles permitirão que você visualize, reutilize e torne o desenvolvimento do kit o mais confortável possível. Eu pessoalmente não uso nenhum desses porque acho que essa integração é mais do que suficiente e o resto continuará no GitHub. Na segunda parte, vamos falar sobre o GitHub. Github está relacionado para obter o que é o GitHub. Você saberá tudo isso no próximo vídeo. Vejo você lá. 12. Trabalhando com Git - Parte 2: Olá, Bem-vindo à segunda parte da boa série. Neste vídeo, vamos falar sobre o GitHub. O que é o GitHub e por que precisamos dele? Vamos como lembrar, eu tenho o pequeno projeto bom da primeira parte em que tenho dois arquivos e alguns commits no terminal, se eu conseguir o log, poderei ver o histórico do Git desse projeto. Agora, a questão é o que acontecerá se eu for excluir essa pasta do projeto de teste do meu PC, meu projeto vai desaparecer completamente? E a resposta para essa pergunta realmente será o GitHub. Ele virá em nosso resgate. Github é um serviço de hospedagem para bons projetos, assim como temos hospedagem para sites, GitHub é um serviço de hospedagem ou plataforma para bons projetos. Se eu for ao Google e procurar um GitHub, ele me levará ao site oficial. Se você ainda não tem uma conta do GitHub, sugiro criar uma já agora, neste momento, já fiz login. Quero mencionar que existem alguns outros serviços de hospedagem populares para bons projetos, como o Git lab ou talvez o Bitbucket. A diferença entre eles será nos recursos e integrações que eles dão a você. Github é o mais comum. Tudo bem, agora, temos nossa conta do GitHub aqui, e gostaríamos de hospedar nosso bom projeto que temos localmente em nosso PC, no GitHub. Como podemos fazer isso. Então, primeiro precisamos criar um repositório remoto no GitHub. Se eu clicar no sinal de mais e no canto superior e clicar em novo repositório, ele solicitará meus novos detalhes do repositório. Um repositório é basicamente um projeto bem, que você coloca no GitHub. Então Repositório significa projeto, mas no GitHub, então nome do meu repositório será meu projeto. Deixarei a descrição vazia a visibilidade do repositório de que pode ser repositório público e privado. Se você escolher público, seu repositório ficará visível para todos, mas somente pessoas autorizadas poderão contribuir com esse repositório se ele for privado, ninguém jamais conhecerá e verá esse repositório. Então, vamos escolher privado e, em seguida, vamos clicar em Criar Repositório. Então, nesta etapa, criamos um novo projeto no GitHub. Agora, precisamos associar a hora Local good project que temos em nosso PC com um repositório remoto no GitHub. Podemos fazer isso de duas maneiras, seja por HTTPS ou através do túnel SSH. Ssh é uma opção disponível, mas o GitHub recomenda HTTPS porque é mais simples e fácil de configurar, vamos usar HTTPS. Você já pode notar que GitHub sugere algumas etapas como podemos associar nosso código local ou projeto local ao repositório remoto. Vamos seguir o segundo passo para enviar um repositório existente porque nosso projeto local bom pode ser chamado de repositório Git local. Então, vamos apenas copiar o primeiro comando daqui e colocá-lo no terminal. Então, o que o git remote adiciona origem? Vamos primeiro executar esse comando e vamos ver o que vai acontecer. Nada é impresso e isso é totalmente bom. Mas agora nosso bom projeto local sabe sobre esse repositório remoto. Podemos verificar se digitando git remote dash v, você verá origem e verá URL do repositório que copiamos daqui. Ele também está disponível aqui. Agora, vamos dar uma olhada mais uma vez neste comando. Portanto, temos git remote add. Este é o comando para associar nossos repositórios. Origin é o nome de um alias que atribuímos a esse URL porque é mais fácil sempre se referir a apelido ou a um alias em vez de URL o tempo todo, que era origem. Este é o nome mais comum. Certo. Agora, o que precisamos fazer para aplaudir nossos arquivos locais para a hospedagem, precisamos fazer git push do que o alias que associamos ao nosso URL do repositório, que será origem e o nome do branch que queremos implantar. Então git push origin master. Se abrirmos novamente e o Git Hub, veremos que ele sugere um bom branch main e, em seguida, git push origin main como lembro Eu já mencionei que confusão há cerca de um ano que a comunidade quer mudar nome da ramificação padrão do mestre para o principal, mas vamos continuar usando o master agora. Então, vamos usar git push origin master em vez de git push origin main. Vou executá-lo. E você verá que a nova ramificação foi criada nessa taxa de URL. Vamos voltar ao GitHub, atualizar a página e o boom, podemos ver que tudo está visível aqui. Então, o que podemos fazer no GitHub. Github, podemos ver nossa boa história completa. Podemos ver todos os arquivos e podemos ver no momento que este comando para esse arquivo foi criado, ok, Então, três horas atrás foi o último commit para esse arquivo e para esse arquivo também para testes, sim, podemos clicar em Arquivos para visualizar o conteúdo. Na verdade, podemos clicar em commits para ver quais alterações foram feitas nesse commit. Então, para que algum arquivo editado seja comprovado, modificamos ou removemos essa linha e adicionamos essas duas linhas. Verde é o que foi adicionado. Vermelho significa algo que foi removido. Vamos voltar ao repositório aqui. Também podemos ver um bom histórico completo clicando nesse botão. E podemos ver que temos três commits. Podemos navegar no repositório neste momento, no histórico. Se clicarmos, podemos ver neste momento que havia apenas um arquivo. Vamos voltar ao repositório principal novamente respondendo à pergunta principal, por que precisamos do GitHub? Precisamos do GitHub para colaborar com outras pessoas ou para tornar nosso projeto portátil. O que quero dizer é que suponha que perdemos acidentalmente essa pasta do projeto de teste em nosso PC local. Por algum motivo, ele simplesmente não existe. No entanto, nosso projeto existe no GitHub. Então, o que podemos fazer, na verdade não podemos carregar nosso projeto do GitHub e colocá-lo em nosso PC local clicando neste botão verde, temos algumas opções aqui. Podemos baixar zip ou podemos clonar. Então, se clicarmos em Download Zip, e se vamos abrir esse zip, você verá todos os arquivos dentro. Então, essa é uma maneira. A segunda maneira é clonar esse repositório usando a CLI. Então, vamos escolher a conexão HTTPS. Vamos copiar esse URL. E agora suponha que meu projeto de teste aqui não exista no PC. Eu o perdi. Então, se eu quisesse recuperá-lo ou recuperá-lo, farei git clone e, em seguida, o URL que copiei. Então ele copiará, criará uma nova pasta chamada meu projeto e colocará todos os arquivos dentro. Se eu for inspecionar minha pasta do projeto, você verá algum file.txt e testará, sim. Mas também se eu vou para minha pasta Project e se eu fizer, infelizmente F, para visualizar arquivos ocultos, haverá outra pasta Git aqui. Então isso ocorre porque quando você clona um repositório, ele já virá com uma boa pasta com a configuração do Git. Imagine que o projeto de teste nunca existiu nesse PC. Eu clono o repositório usando HTTPS e git clone. E agora minha configuração do Git já está concluída. Eu posso simplesmente navegar até a minha pasta Projeto e tudo já está lá. Configuração para mim. Agora posso continuar a fazer novos commits, fazer algumas alterações e, em seguida, fazer o upload para o GitHub novamente, deixe-me excluir minha pasta do projeto. Na verdade, não preciso disso. Vou navegar de volta. Agora. Como posso realmente continuar a desenvolver depois de ter meu projeto no GitHub? Essa é uma boa pergunta. Bem, assim como antes, se eu precisar introduzir novas mudanças no projeto, continuarei fazendo minhas alterações. Talvez eu adicione outra linha com olá dois aqui e salve-a. Agora, como você se lembra, eu tenho mudanças não rastreadas. Se eu digitar git status, você verá que o arquivo foi modificado. Então, novamente, preciso adicionar esse arquivo ao estado do palco. Vou colocar git add dot. Você verá aqui, ele aparece agora em mudanças preparadas e agora eu posso me comprometer. Então git commit adicionou hello two. Agora, se eu digitar git log, poderei ver o novo commit na parte superior. Agora eu tenho quatro commits, mas se eu voltar ao GitHub, não vejo isso aqui porque GitHub e Git, eles não estão magicamente sincronizados entre si. Sempre que você fizer novas alterações no seu PC, elas são locais. Eles estão disponíveis somente no seu PC. E se você quiser vê-los na hospedagem, você precisa enviá-los para hospedagem. E para fazer isso, novamente usamos o comando git, push, Good Push e o nome de LES e nosso alias. Podemos verificar se com git remote dash v, nosso Ls é origem, o que leva a este repositório, que está correto. Então, vou fazer git push origin e depois dominar o nome da ramificação. Agora vejo que minhas alterações foram carregadas. Eu atualizo a página. E outro comitê foi adicionado aqui há um minuto, o que está correto. Se eu clicar nessa mensagem de commit, você verá que essas duas linhas para editar exatamente o que acabei de fazer. E mais uma vez respondendo à pergunta principal, o que o GitHub faz? Por que precisamos disso? Github é necessário para a colaboração entre pessoas e para tornar nosso projeto o mais portátil possível. No próximo vídeo, falaremos sobre filiais e como as pessoas estão colaborando usando o GitHub. Vejo você lá. 13. Trabalhando com Git - Parte 3: Olá, bem-vindo à terceira parte da boa série. Na última parte, implantamos com sucesso nosso bom projeto local no GitHub. E sabemos o que é o GitHub. É uma plataforma de hospedagem para colaboração e usamos o GitHub para tornar o projeto superior o mais portátil possível. Nesta parte, vamos descobrir esses principais conceitos de bons ramos frios. E vamos falar sobre como podemos colaborar no GitHub. Vamos. Primeiro de tudo, vamos falar sobre filiais. Este misterioso ramo mestre esteve aqui desde o início. Mas o que isso significa? Se vamos digitar git branch no terminal, veremos que você terá apenas master, mas podemos criar quantas ramificações quisermos. Então, branch é apenas aquela outra cópia do nosso projeto. Vejamos isso por meio de um exemplo. Então, vamos criar uma nova ramificação. Para criar uma nova ramificação, temos que digitar git checkout do que menos b e, em seguida o nome da ramificação que queremos criar, vamos chamá-lo de meu recurso dash. Você pode ver mudar para uma nova ramificação. Meu recurso, novamente, digito git branch. Eu tenho mestre e tenho meu recurso e um conjunto de mestre. Eu vejo meu recurso agora, isso ocorre porque esse é meu branch ativo neste momento. Então, o que você vê aqui é sua ramificação atualmente ativa. Agora, qual é a diferença agora, essas duas ramificações são iguais, mas suponha que eu queira desenvolver um novo recurso no meu aplicativo, mas não quero tocar no meu código principal. Meu código principal permanece inalterado, mas eu queria desenvolver um novo recurso. É aqui que entram os ramos. Então, meu branch master contém meu aplicativo mais recente para o código implantado na produção. Funciona agora. E, ao mesmo tempo, eu queria desenvolver um novo recurso. Então eu crio uma nova ramificação chamada meu recurso, e agora começo a desenvolver nesse novo ramo. Suponha que eu esteja no meu branch de recurso, eu crio um novo commit. Meu novo recurso será um novo log do console, que será Olá três. Tudo bem? Agora eu confirmo essas alterações. Primeiro eu empurro para o estado do palco e depois faço um novo commit. Eu chamo isso desenvolveu meu novo recurso. Ótimo. Se eu fizer git log para visualizar o histórico, posso ver meu histórico anterior e, em seguida, meu novo commit, desenvolver meu novo recurso. Incrível, mas como isso é útil? Agora, se eu precisar, por algum motivo, voltar para o meu código principal e ver o que estava lá. Agora sou capaz de alternar entre ramificações. Então eu coloquei git branch para ver o que branches fazem metade e, em seguida, posso fazer git checkout master para alternar entre branches, mas desta vez sem sinalização B menos. Agora mudei para branch master. E você pode ver como essa alteração que o dr. fez no meu ramo de recursos desapareceu. Isso ocorre porque essa alteração faz parte da minha ramificação de recursos. Ele não tem relação com o master porque se eu colocar um git log, você verá que eu não tenho esse commit que o libertei no meu branch de recurso, no branch master, é completamente diferente. Então, como você pode ver, Master e meu recurso são algum tipo de cópia do meu projeto que existem ao mesmo tempo, eu posso manipular essas ramificações para desenvolver diferentes recursos. Agora, como posso realmente utilizar esse conceito de ramificação para torná-lo útil para mim ou para pessoas com quem eu colaboro. Então, suponha que existam 10 pessoas que trabalham no mesmo projeto e para convidar pessoas para um repositório e precisam ir para configurações, gerenciar o acesso. E aqui você geralmente convidará colaboradores. Portanto, as pessoas que têm acesso a esse repositório privado poderão fazer alterações nesse repositório. Mas se tudo, se todas as pessoas que trabalham em um projeto vão empurrar para o mesmo ramo principal ou ramo principal. Isso vai ser um pouco uma bagunça. Queremos torná-lo o mais estruturado, surgido quanto possível para manter nossa boa história limpa, legível e sustentável. E para fazer isso, utilizaremos ramos. Suponha que nosso código principal esteja no branch master, que tem o último commit adicionado olá para Eu sou outra pessoa sentada em algum lugar lá fora. Sou colaborador e crio uma nova ramificação, meu recurso que já criei e fiz algumas alterações. Quero enviar essas alterações para o GitHub e quero mesclar essas alterações no código principal, que está localizado novamente na ramificação principal. Então, o que eu preciso fazer, eu preciso primeiro empurrar esse ramo. Para o GitHub. Para fazer isso, farei git push origin porque este é o nosso alienígena para o repositório. Lembramos que git push origin, meu recurso. Vamos esperar um segundo. E agora ele é empurrado e até sugere que criemos uma pull request para meu recurso no GitHub visitando. Vamos falar sobre isso em um segundo. Mas se voltarmos ao GitHub, já vemos que meu recurso tinha push recentes há menos de um minuto. Compare e pull request. Se eu atualizar a página, agora aqui verei duas ramificações. Se eu clicar aqui, tenho o branch master padrão e tenho suas ramificações, meu recurso atualizá-lo há minutos por mim e principal ramo do CEU horas atrás por mim. E aqui posso ver se eu passar o mouse, verei um commit à frente do mestre. Agora, para enviar as alterações que tenho no meu branch de recurso para o master, preciso criar uma pull request diretamente no GitHub. Uma pull request é essa solicitação do desenvolvedor quando você pede aos mantenedores do projeto que mesclem sua ramificação na ramificação principal. Então, basicamente, você quer contribuir e gostaria de empurrar essas alterações para o código principal. Vamos clicar em nova pull request. Vamos nomeá-lo desenvolvido. Meu novo recurso deixará um comentário que, ei, acabei de fazer essa grande mudança. E aqui nós selecionamos isso. Queremos enviar, queremos mesclar minha ramificação de recursos no master. Esses são todos os commits que eu fiz naquela ramificação. Posso criar tantos commits quanto possível. Por exemplo, se eu adicionar outro commit, talvez console.log, olá para, novamente, eu encenar essas alterações, eu as confirmo novamente, nova alteração. Novamente, eu empurro, Good Push origin, meu recurso. A ramificação será atualizada. Mesmo que eu já tenha criado uma pull request, ainda não a criei. Mas, de qualquer forma, então vou clicar em criar , puxar, solicitar. E vamos ver o que temos aqui. Então, primeiro vemos a capacidade de verificação de mesclagem porque pode haver conflitos nessas alterações. Mas como não temos conflitos, está tudo bem. Então, veremos nossos pull requests aqui. Então, agora o que vai acontecer? Eu sou aquela pessoa que sentada ali criando essa pull request, então entra o líder do projeto ou mantenedor do projeto e essa pessoa responsável pela pull request vai aqui e vê que, Ei, essa pessoa queria mesclar essas mudanças. Então ele clica nessa pull request. Ok, ótimo, aquele cara fez uma grande mudança. Oh meu Deus. Quero mesclar essas alterações. Então essa pessoa mescla essa pull request. Então ele seleciona uma das opções aqui. Deixe-me clicar em merge pull request e vamos ver o que vai acontecer. Então, mescle pull requests dessa pessoa, essa ramificação desenvolveu meu novo recurso, confirme mesclagem, mesclagem, solicitação de pesquisa, ramificação de exclusão bem-sucedida e fechada. Vamos clicar em que o branch foi excluído, pull requests, merge. Se eu voltar ao meu projeto aqui, posso ver as pull requests de mesclagem do Sherlock 16, meu recurso, e agora faz parte de um bom histórico. Se eu clicar em commits, verei que primeiro tenho esses dois commits que tive no meu branch de recurso. E além disso, tenho outra pull request de mesclagem de commit. Agora, todas essas alterações que estavam na minha ramificação de recursos foram mescladas no código principal e estão disponíveis aqui. É assim que as pessoas geralmente contribuem por meio de pull request um, todas essas alterações estão no GitHub. Teremos discrepâncias porque temos sete commits no branch master, no repositório remoto, no GitHub em nosso projeto local, ainda estamos tendo meu branch de recurso. E se formos ao master usando git checkout master. E se fizermos git log, veremos que o último commit aqui é adicionado hello two, enquanto aqui está, mesclar pull requests para um. Para corrigir isso, precisamos baixar as alterações mais recentes do GitHub em nosso código local para sincronizar o histórico. Para fazer isso, o comando é muito semelhante ao git push, mas em vez de git push, usaremos git pull. Então, novamente, obtemos pull do que as áreas do repositório e, em seguida, o nome da ramificação a ser extraída. Então, queremos tirar o mestre da origem. Vou executá-lo. E você verá isso ótimo, algo aconteceu. E como você pode ver, agora, todas as minhas mudanças estão aqui. O último commit introduzido, olá quatro e eu, e agora tenho olá no meu código. Muito legal verificar se eu faço git log novamente. E você vê que eu tenho vários pedidos de bomba de Sherlock 16, a propósito, para sair desse estado quando, quando uma boa história transborda, você pode simplesmente digitar q e ele o levará para o terminal. Tudo bem, eu diria que provavelmente é isso, é assim que as pessoas usam o GitHub para colaborar. O modelo seria um pouco diferente se for um repositório público e você quiser contribuir para um projeto de código aberto. Mas não vamos cobrir isso nesta série. Isso é mais do que suficiente para entendermos como o Git funciona e como as pessoas colaboram umas com as outras. Então, novamente, vou repetir o fluxo mais uma vez normalmente. E se você quisesse criar uma nova mudança e estiver trabalhando em um projeto. Primeiro, você cria uma nova ramificação usando git checkout menos b e o nome da ramificação, pode ser qualquer coisa. Tudo bem, então essas cópias, essa nova ramificação será criada a partir da ramificação que estava ativa no momento em que você executar esse comando. Portanto, essas ramificações agora conterão todos os commits que você teve ao executar este comando, ok, você continua desenvolvendo o branch de conduta, faz quantos commits precisar para concluir o recurso. Em seguida, você envia esse branch para o GitHub usando um bom Push. Em seguida, ele aparece no repositório. Em seguida, você vai para suas pull requests e cria uma nova pull request para mesclar essa ramificação que acabou de publicar no GitHub no código principal, na ramificação principal. E então uma pessoa responsável virá e verá que, Ei, aquele cara quer mesclar esse ramo no código principal. E quando essa pull request for mesclada ou aceita, suas alterações serão mescladas no código principal. Depois disso, todos que estiverem trabalhando em um projeto, eles serão obrigados a extrair as últimas alterações do branch principal usando o comando git pull. E é isso. Este é o fluxo básico de parabéns de colaboração do Git e do GitHub. Acho que este é o nosso acabado para uma boa série, e eu vou vê-lo na próxima. 14. Instalando o Node): Olá, Neste vídeo, estamos prestes a instalar o Node.js no Windows. O que é NodeJS e por que precisamos disso é explicado no próximo vídeo. O que precisamos fazer é abrir qualquer navegador e acessar o Google. E o Google não procurará GS. O primeiro link será o site oficial. Aqui temos duas versões a serem baixadas, LTS e versão atual. A versão atual é a versão mais recente disponível para download, e o LTS é a versão estável mais recente. Não precisamos complicar demais. É por isso que pegamos LTS. Clique nesse e abra o instalador. Espere um pouco e clique em Avançar. Sim, eu aceito Próximo, mude o caminho se você precisar. Em seguida, nesta etapa não precisamos de GS, NPM e caminho de atitude. Em seguida, nesta etapa temos ferramentas para módulos nativos e queremos selecionar essa opção. O que é isso e por que precisamos disso? Assim como diz, alguns módulos npm precisam ser compilados a partir do CC plus plus ao instalar. O que isso significa? Isso significa que existem algumas bibliotecas, módulos ou pacotes que instalaremos durante nosso desenvolvimento que exigem alguns binários nativos específicos para o sistema operacional, no nosso caso, janelas. Portanto, as ferramentas que compilarão esses músculos lisos são ferramentas de compilação Python e Visual Studio. Então, essa opção apenas os instalará se eles estiverem faltando agora, certo? Clique em Avançar e pressione Instalar. Não vou clicar em Instalar porque já não tenho GS instalado. Mas para você, isso é o que vai acontecer. Quando você clica nesse botão, você verá uma nova janela CMD aparecerá. E ele verá algo como vamos fazer e instalar esse pedido que exigiremos esse número de espaço. Basta fechar essa janela e depois disso, você verá que outra janela será aberta, que é a janela do PowerShell. E haverá todo o registro de instalação. Então, espere algum tempo até que esteja pronto e então você está bem. Nenhum JS é considerado instalado. Agora vamos verificar isso. Como fazer isso. Clique no painel Iniciar e procure cmd. Então abrimos isso. E no CMT nós digitamos espaço do nó, traço, versão traço. Pressione Enter e você verá a versão que acabou de instalar. Pode ser possível que, ao digitar nó dash, versão dash, você verá algo como nó não é reconhecido como um comando interno ou externo. Portanto, temos que encontrar outra maneira de verificar nossa instalação. Para fazer isso, precisamos voltar para iniciar o Painel do que para o painel de controle. E então vamos procurar programas e recursos, ok? Aqui precisamos verificar se não temos GS na lista. Portanto, se você não tem GS na lista aqui, ele lhe dá aviso não reconhecido como um comando extra interno. Então você precisa fazer um pequeno ajuste na configuração do sistema. Então, o que você precisa fazer é clicar novamente no painel Iniciar no tipo de pesquisa ENV e selecionar editar as variáveis de ambiente do sistema. Em seguida, clique nas variáveis de ambiente. E aqui, em variáveis do sistema, você deve encontrar a variável de caminho. Clique duas vezes sobre esse. E na lista você não verá os Arquivos de Programas C. Sem JS, que é meu caminho de instalação sem jazz. Então, porque você não tem isso aqui na lista, você vê que nó não é reconhecido, ok? Então, o que você precisa fazer, você precisa clicar em Novo e adicionar seu caminho de instalação sem GS. Portanto, se você não modificou a opção na instalação, seria Arquivos de Programas C, NodeJS também. Então, clique em Novo, cole o caminho aqui, ok? Ok, ok, então basta reiniciar o terminal. Em seguida, tente o nó dash, a versão dash. Mais uma vez. Depois disso, você deve ver a versão. E é basicamente isso. Parabéns, você acabou de instalar o NodeJS no Windows. Vejo você no próximo. 15. Instalando o macOS (macOS): Oi, Neste vídeo, mostrarei como instalar o NodeJS no macOS. Vamos. Como sempre, você acessa o Google primeiro e digita NodeJS, vá para o primeiro URL, que é o site oficial, depois navegue até a página de downloads e clica no instalador do macOS. O download começará automaticamente. Abra o arquivo baixado. Você verá o assistente de instalação clicar em Continuar, depois aceitar os termos, depois verificar o caminho de instalação e clique em Instalar. Ele solicitará sua senha e tudo bem. Aguarde a instalação do GS logo após o processo de instalação, você não terá GS e NPM em seu sistema para verificar a instalação. Vamos para o terminal, vamos almoçar mal. Em seguida, procure o terminal para verificar o nó do tipo NodeJS traço V, que significa a versão. Ele deve imprimir a versão que você instalou. E da mesma forma, também precisamos verificar o NPM. Então digite npm dash v, e é isso. Vejo você no próximo. 16. NPM, Parte 1: Olá, bem-vindo a conhecer o vídeo de introdução do GS. Agora vamos falar sobre o que não é GS. Por que precisamos dele e como somos capazes de usá-lo? Vamos primeiro, o que não é GS sabe GS é o ambiente de tempo de execução JavaScript. Isso significa que é algo que nos permite executar JavaScript. E você provavelmente vai pensar, por que não precisamos de GS? Porque temos JavaScript em execução no navegador e esse é o ponto. Hoje em dia, somos capazes de executar JavaScript fora do navegador com a ajuda do NodeJS, podemos usar JavaScript para escrever aplicativos móveis. Podemos usar o JavaScript para escrever aplicativos de desktop. Basicamente, podemos fazer qualquer coisa com JavaScript agora. Graças à nota, sim, porque nos permite executar JavaScript fora do navegador. Por exemplo, se eu abrir o navegador aqui, clico em Inspecionar e, em seguida, vou para o console. Portanto, esse é o ambiente do navegador. Sou capaz de escrever qualquer JavaScript que eu quiser aqui. Por exemplo, se eu quiser digitar console.log 5 mais 2, ele imprimirá seis para mim. Isso é ótimo, mas isso está dentro do navegador. Se eu quisesse executá-lo em outro lugar, eu não teria permissão para fazê-lo. Mas com a ajuda de nós, sim, poderei fazer isso. Vamos para o código VS e deixe-me criar uma nova pasta de projeto. Vou para a pasta Meus Projetos, e aqui vou colocar o teste GS. Selecionarei essa pasta. E agora vamos criar um novo arquivo aqui, vamos chamá-lo de test.js. Antes de escrevermos qualquer coisa, primeiro vamos garantir que não temos JS instalado. Somos capazes de acessá-lo. Para isso, abrirei meu terminal integrado. E para acessar o NodeJS, só preciso digitar nó. Depois que eles executarem o comando node, entrarei no ambiente Node.JS. Então, aqui, poderei executar JavaScript. Por exemplo, a mesma coisa que eu fiz no log do console do navegador 2 mais 4. Muito incrível. Esta é a prova de que o JavaScript foi executado fora do navegador. Mas isso não é muito conveniente para nós sempre escrever JavaScript dentro do terminal. Então, para sair desse modo, que pressionará Control mais C várias vezes. Ótimo. E agora, em vez disso, vamos escrever alguns arquivos JavaScript que mais tarde executaremos sem JS antes de entrarmos em arquivos, eu só quero mencionar que todos os arquivos, todos os arquivos JavaScript que são executados dentro do ambiente Node.JS será um módulo. Um módulo é um arquivo JavaScript autônomo. Isso significa que não se sabe sobre o mundo exterior apenas o que está escrito por dentro. Vamos primeiro criar talvez Sou audível? Const cinco é igual a cinco. E agora vamos consolar o log de pontos 5 e pressione Salvar. É isso. Acabamos de criar nosso primeiro roteiro. Agora vamos executá-lo para executar um arquivo, temos que digitar nó e, em seguida, o nome do script que gostaríamos de executar. Então, isso vai ser o teste GS. Eu executo esse comando e você pode ver cinco no console porque eu apenas consolo o log 5. Se eu for remover essa linha, vou comentá-la. E vou tentar executar o script novamente. Nada será impresso. E isso é óbvio porque não fazemos nada lá dentro. Agora, vamos tornar nossa tarefa um pouco mais difícil. E se tivermos dois arquivos para módulos? Deixe você criar um segundo ponto aqui, e vamos colocar uma string aqui. Talvez meu nome, eu imprima Andrew. E o que eu quero fazer, quero de alguma forma compartilhar informações entre esses dois módulos. Então eu queria passar meu nome do segundo gs para o teste. Sim. E eu sou capaz de fazer isso por meio de importação e exportação. Então, para exportar algo de um módulo, usamos o módulo. Então, nossos especialistas do que exportamos um objeto. E neste objeto, colocarei minha variável de nome assim. Então eu posso fazer isso realmente assim. Meu nome, então chame meu nome. Mas em JavaScript podemos usar uma abreviação. Podemos simplesmente colocá-lo assim e funcionará muito bem. Agora meu nome é exportado do segundo gs. Vamos tentar importar isso. Se eu voltar para Ts, gs, deixe-me remover tudo isso. Vou colocar um const que vou nomear minha exportação algo como. Importou meu nome, seja o que for. E para importar o que eu exportei daqui, preciso digitar obrigatório. E por dentro exigem, eu coloco caminho para esse módulo, que será apenas o segundo GS. Não preciso especificar a extensão. Então, coloquei ponto e barra aqui para especificar que esse arquivo está localizado nesta pasta. Agora, o que vou fazer, simplesmente o log do console importou meu nome. Eu salvo o arquivo, volto para o terminal e, novamente, nó, teste, GS. Boom, o que eu vejo, eu tenho um objeto. E esse objeto contém minha chave de nome. Exatamente o que eu exportei do segundo, sim, na verdade, podemos renomear isso para o segundo módulo importado. E então eu posso fazer referência ao segundo módulo importado ponto meu nome porque este é um objeto e tem chave meu nome. Eu salvo, executo o script novamente e entrei impresso no console. É assim que o NodeJS funciona simplesmente criando módulos diferentes que compartilham dados entre si. Esse sistema com uma exigência e com exportações de módulo é chamado GS comum, que é escrito assim. Vírgula gs. Este é um sistema de exportação de importação nativo em Node.JS. No entanto, neste momento, comunidade NodeJS está trabalhando ativamente e usando o sistema que é chamado de módulos ECMO Script. Portanto, esses módulos fazem parte do ambiente do navegador e, no momento, são experimentais em um ambiente Node.JS. Portanto, eles são ligeiramente diferentes das exportações de exigências e módulos, mas são mais fáceis e intuitivas de usar. Vamos experimentá-los. O que você acha para usar moléculas ACML Script no ambiente Node.JS, temos que adicionar outra extensão aos nossos módulos. Então, em vez de js, precisamos usar o MGS, que será módulo GS, MGS e renomear esse arquivo também, vai ser mgs. Então, em vez de obrigatório, vou comentar essa linha pressionando Control Slash. E, em vez disso, usarei Importar. Então, como exportamos um objeto, colocarei novamente colchetes encaracolados. E vou especificar que preciso importar meu nome. É importante especificar o mesmo nome porque se eu for especificar algo diferente, ele não existe no objeto exportado, certo? Então vou colocar meu nome do segundo módulo. Ótimo. E agora vou registrar meu nome no console. E no segundo MGS, em vez das exportações de módulos, simplesmente digito exportar meu nome. É isso. E parece muito, muito mais limpo que o CommonJS. Agora vamos tentar um teste de nó executado. Sim, e nós teremos, não é possível encontrar o módulo aha IC. Isso ocorre porque eu provavelmente tenho que especificar a extensão. Deixe-me experimentar. Sim, exatamente. Portanto, há mais uma desvantagem com o módulo usando scripts ECMO no estado atual do NodeJS, tenho que sempre especificar a extensão com CommonJS, posso admitir especificar a extensão quando a Importar módulos diferentes como esse, mas com o módulo de scripts ECMO, eu tenho que fazer isso. O resultado é o mesmo. Vou executar o script. Eu tenho Andrew, mas você pode ver agora ele usa o módulo de scripts ECMO em nosso projeto. Quando faremos todas essas coisas de desenvolvimento, usaremos o ambiente Node.JS e vamos utilizar os módulos Achmat Script. Você pode ver que este é um exemplo muito simples. Ele usa scripts únicos aqui, nada complicado. No entanto, obviamente precisamos de algo mais complexo e esse é o nosso tópico para o próximo vídeo. Vejo você lá. 17. NPM, Parte 2: Ei, bem-vindo à segunda parte da introdução do NodeJS e à última parte que discutimos o que é não sim, e como podemos executar scripts únicos. Neste vídeo, vamos falar sobre o NPM e como podemos usar o npm para gerenciar dependências de projetos e projetos. Vamos. Primeiro de tudo, o que é npm? Npm significa Node Package Manager e já vem com o NodeJS. Portanto, se você não tiver JSON instalado, você já tem o NPM para verificar se dentro do terminal, basta digitar npm. Há uma versão dash e ela imprimirá a versão do NPM atualmente instalada. Agora, como podemos usar o npm ou o que ele faz por nós? Bem, o problema é que em projetos JavaScript reais, existem dependências ou pacotes de projeto. Portanto, essas são essas bibliotecas, módulos diferentes da Internet ou ferramentas diferentes que instalamos em nosso projeto. E npm é a ferramenta que nos permitirá fazer isso. Então, para instalar esses pacotes, mas primeiro, como inicializar o npm dentro da nossa pasta do projeto. Para fazer isso, temos que usar o comando npm init. E depois de executar esse comando, ele solicitará algumas coisas, como nome do pacote, versão e outras coisas. Basta ignorar isso pressionando enter o tempo todo. Quando o comando for concluído. Na rota do projeto, você verá pacote de arquivo package.json Jason é aquele arquivo manifesto que descreve nosso projeto dentro, podemos ver o nome do projeto, talvez a descrição da versão do projeto. Se vamos colocar as luzes do autor e ver se temos algum script e algumas outras seções sobre as quais falaremos em um segundo. A questão é: qual pacote JSON faz para nós? Como isso pode ser útil? Bem, vamos para o navegador. Vamos procurar o NPM no Google e vamos acabar no site oficial do npm. Npm tem o registro NPM. Então Node Package Manager é uma ferramenta que nos permite gerenciar pacotes dentro do nosso projeto. Mas de onde vêm esses pacotes? Eles vêm do registro NPM. O registro NPM é aquele oceano de diferentes pacotes, ferramentas e bibliotecas que podemos instalar em nosso projeto usando npm. Então, neste site, você pode procurar pacotes diferentes. Existem milhões, bilhões de bibliotecas diferentes que podemos usar. Mas, por enquanto, vamos procurar o que eu preparei , que é cowsay. Vamos clicar nesse. E agora podemos ver a página oficial para estes pacotes nessa página, podemos encontrar sua documentação, como podemos instalar esse pacote, o que ele faz, como podemos usá-lo e todas as outras coisas. Podemos ver que ele tem para dependências. O problema é que os pacotes publicados no registro do NPM têm dependências, e essas dependências também são pacotes publicados. E esses pacotes também podem ter Dependências. Dependências, dependências e dependências de dependências são chamadas de dependências de pares. Nessa página, também podemos encontrar algumas informações sobre o assunto, como a versão, quantos downloads semanais ele tem o autor publicado pela última vez e algumas outras coisas. Vamos ler a documentação. O que vemos aqui? Primeiro de tudo, o que esse pacote faz? Bem, este pacote é basicamente muito simples. Seu único propósito é apenas imprimir essa vaca no terminal. Então, vamos ver a parte de instalação, npm instalar menos g cowsay. Vamos copiar esse comando e vamos colocá-lo em nosso terminal. Vamos ver o que vai acontecer. Assim, podemos ver que algo está acontecendo. Podemos ver que a instalação já foi bem-sucedida. Podemos ver os pacotes Editar 41 e a versão que instalamos, que é 1.5. Por que 41 pacote? Assim como mencionei anteriormente, pacotes têm suas próprias dependências, e essas dependências têm suas próprias dependências. E, eventualmente, temos essa árvore de dependência. É por isso que, no final, temos 41 pacotes no total. Temos o npm instalado cowsay. O que ele fez? Bem, ele acabou de instalar o cowsay em nosso sistema como um pacote global. Como um pacote global porque nós menos o sinalizador g para verificar se podemos digitar npm list menos g, então dash, dash depth é igual a 0. Vamos executar esse comando e vamos ver o que é impresso. Já tenho alguns pacotes instalados aqui globalmente, mas na sua lista você verá cowsay. Então, o que isso significa? O que isso nos dá? Isso significa que agora podemos usar o pacote como CLI globalmente em nosso sistema. Vamos ver o parque de uso, Cowsay JavaScript. Vamos copiá-lo. E vamos tentar executá-lo no terminal. Eu tenho uma pequena vaca bonita aqui dizendo JavaScript. Então isso é exatamente o que esse pacote faz, e podemos usá-lo como um CLA em nosso terminal. E isso não importa de onde ele está disponível globalmente. Se eu abrir outra instância do Git Bash aqui, ainda poderei usar cowsay. Porque novamente, instalamos o cowsay como um pacote global. Isso significa que podemos usá-lo em qualquer lugar. Existem dois tipos de pacotes, ou eu diria duas maneiras de instalar um pacote. Primeiro, podemos instalá-lo globalmente, assim como você vê aqui. Portanto, quando um pacote é instalado globalmente, ele não é limitado a nenhum projeto, é instalado globalmente em seu sistema. A segunda maneira é instalar um pacote como dependência do projeto. Quando um pacote instalado como dependência de projeto, em primeiro lugar, ele não está disponível globalmente. Ele se torna disponível apenas naquele projeto em que foi instalado, vamos primeiro desinstalar o cowsay como um pacote global e, em vez disso, vamos instalá-lo como uma dependência do projeto. Então, primeiro vamos digitar npm instalar menos g cow sake. Você verá no final removido o grau 41 do pacote. Agora, para instalar o cowsay como uma dependência de projeto, temos que fazer o npm instalado cowsay, mas desta vez sem sinalizador de menos g, vamos executar esse comando e vamos ver o que vai acontecer. O que há de novo no File Explorer lateral. Então, primeiro, se abrirmos o pacote Jason, veremos a nova seção de dependência. Então, como o pacote Jason é nosso arquivo de manifesto, ele conterá, ele listará todas as dependências que instalamos. Então, instalamos apenas um cowsay de dependência dessa versão. Agora também vemos package.json. E package.json aparece sempre que você instala qualquer finalidade package.json de dependência.json é procurar versões das dependências instaladas e dependências de dependências. Dessa forma, podemos evitar problemas diferentes com resoluções de versão. E também temos pasta de módulos de nó. pasta de módulos de nó é aquela pasta em que todos os pacotes foram instalados. Se abrirmos essa pasta, veremos vários pacotes diferentes aqui junto com cowsay. Estes são aqueles 41 pacotes que vimos foram instalados. Eles estão aqui em módulos Node. Se quisermos excluir essa pasta, eles serão excluídos. Agora, vamos voltar para cowsay e vamos ver como podemos realmente usar esse pacote. Então, se rolarmos para baixo, podemos ver o uso como um módulo. Lembre-se de que eu disse a eles que todos os arquivos em Node.JS, nossos módulos são iguais aos pacotes. Como os pacotes no registro NPM também são arquivos JavaScript, isso significa que existem módulos. Então, vamos ver como podemos usá-lo como um módulo. E olhando para esse trecho de código, posso dizer que este exemplo usa require, que significa que ele usa o sistema de importação CommonJS. Mas agora sabemos que há CommonJS e também há módulos ECMO Script. Então, em vez disso, vamos usar módulos atmosféricos. Então, vamos copiar esse exemplo. E vamos colocá-lo dentro do nosso teste mgs. Mas em vez de exigir, eu uso na importação do meu script. Então, vamos digitar cowsay de importação de cowsay. E aqui eu tenho que especificar o nome do pacote, onde o nome da dependência do pacote JSON. Não preciso especificar o caminho que não preciso referenciar módulos de nó. Eu só preciso digitar o nome da dependência, que vai ser cowsay. Agora, vamos excluir isso e vamos excluir isso, e vamos salvá-lo. E vamos tentar executar esse script. Vou digitar o nó test.js. E vamos ver, novamente temos aquela vaca dizendo que sou um Moodle, mas agora cowsay faz parte do nosso projeto. Quando o instalamos globalmente, era independente. Era apenas uma ferramenta em nosso sistema que podemos usar através do terminal. Mas desde agora cowsay faz parte do nosso projeto, estamos limitados a cowsay neste projeto específico. Se eu for remover a pasta de módulos de nó, vamos avançar e excluí-lo completamente. E se eu vou tentar executar esse arquivo novamente, você verá que não conseguirá encontrar pacote cowsay porque acabamos de excluir todos os arquivos necessários para executar o cowsay. Então, para reinstalar os pacotes listados no pacote Jason listado em nosso projeto, temos que digitar o npm instalado sempre que não tivermos pasta de módulos de nó, mas precisamos instalar os pacotes. Acabamos de digitar npm install. Então, o que ele vai fazer, ele vai olhar dentro do pacote Jason. Ele procurará a seção de dependência e instalará pacotes ausentes. É isso. Agora você pode ver novamente no pacote 41, se eu executar o script novamente, a vaca estava lá. Incrível. Vamos inspecionar o pacote JSON e vamos encontrar a seção de scripts aqui. Quero falar sobre esta seção agora, o problema é que nos projetos, existem alguns scripts específicos de projetos. Portanto, esta seção é chamada de scripts NPM. Portanto, geralmente scripts específicos do projeto são definidos por meio de scripts NPM. Já temos um script de teste definido aqui, mas vamos removê-lo e vamos definir nosso próprio script. Pode ser qualquer coisa, podemos nomear o que quisermos. Por exemplo, meu script de teste. E aqui precisamos digitar o que o script fará. Por exemplo, se no terminal imprimir algo na saída, eu usaria o comando echo, echo, hello e hello é impresso. Então, bem, aqui podemos definir a mesma coisa. Por exemplo, meu script de teste executará echo hello, por exemplo, no código hello. Agora, para executar esse script NPM, tenho que digitar npm run e o nome do script, que será meu script de teste. Depois de executarem esse comando, esse comando procurará o pacote JSON nesta pasta, e ele olhará dentro desta seção de script, e ele encontrará meu script de teste, e então ele simplesmente executará o que estiver escrito aqui. Vamos experimentá-lo. Você pode ver que eu tenho Hello, basicamente o mesmo resultado. É isso, por que pode ser útil. Bem, há algumas situações em que podemos ter um roteiro muito, muito longo aqui. Imagine que seja assim. E agora, em vez de escrever tudo isso, o tempo todo, podemos simplesmente executar o npm, executar meu script de teste, e isso fará a coisa. É isso. Vamos falar sobre scripts NPM mais em detalhes uma vez que vamos lançar um projeto React real por enquanto, vamos deixá-lo vazio. Mais uma coisa que quero mencionar aqui é que as dependências do projeto podem ser de dois tipos. Na verdade, existem dependências regulares que usamos em nosso código-fonte, e pode haver dependências de desenvolvimento. Portanto, as dependências de desenvolvimento também fazem parte do projeto, mas não são referenciadas dentro do código-fonte. Eles são usados apenas para desenvolvimento. Portanto, esses pacotes que vamos instalar para desenvolvimento serão pregadores e ES lint. E vamos instalá-los como dependências surdas. Falaremos sobre eles nos próximos vídeos. Eles serão usados para facilitar nosso desenvolvimento, mas são opcionais. Se vamos remover dependências de desenvolvimento, o projeto ainda poderá ser executado. No entanto, se removermos essa dependência daqui, se vamos remover módulos de nó, o projeto não poderá ser executado porque depende do cowsay. Portanto, se removermos dependências de desenvolvimento, o projeto ainda poderá ser executado. Mas se removermos a dependência principal, o projeto não será executado porque agora a dependência está faltando porque nosso projeto depende disso. Mas as dependências de desenvolvimento são apenas dependências para nosso ambiente de desenvolvimento. Ele não tem influência direta no código-fonte. Vamos falar sobre isso mais uma vez uma vez que vamos falar sobre pregador na gasolina. Mas, por enquanto, acho que é suficiente. Todos os projetos JavaScript são gerenciados assim usando npm, os pacotes de registro NPM, você terá o JSON empacotado em sua pasta raiz. Você terá dependências instaladas a partir do registro do NPM. Então você fará referência a essas dependências em seu código-fonte. No final do dia, quando você tiver que desenvolver o projeto ou precisar construir o projeto, você terá scripts NPM definidos aqui no pacote Jason. E é isso. É assim que todos os projetos JavaScript se parecem. É isso para o NodeJS. E eu vou te ver no vídeo ES fiapos e pregadores. 18. O que são prettier e ESLint?: Ei, neste vídeo eu gostaria de falar sobre pregador em ES lint. Quais são essas ferramentas? Por que nos importamos e como eles vão nos ajudar? Vamos descobrir isso juntos. Então, a primeira coisa que quero mencionar que neste vídeo, vou reutilizar o mesmo projeto que criei no vídeo de introdução do Node.JS. Como você se lembra, ele contém apenas uma dependência, que é cowsay, e nós a usamos dentro apenas do MGS. Vamos começar. Pregadores uma ferramenta que vai formatar todos os nossos arquivos. Ele tem apenas um propósito para formatar arquivos. Ele ganha o conflito predefinido. Então, vamos descobrir como podemos usar o pregador. Se formos ao Google e procurarmos um pregador, você acabará no site oficial. Vamos para a documentação oficial de instalação e vamos segui-la. Primeiro pregador instalado localmente. Vamos copiar esse comando e vamos colocá-lo dentro do terminal. Portanto, a sinalização save-dev dentro do comando significa que esse pregador de pacotes será instalado como uma dependência de desenvolvimento. Se vamos abrir package.json, veremos uma nova seção aqui, dependências de desenvolvimento, que são dependências do desenvolvedor. E veremos pregador aqui. Agora. Vamos continuar com os cães. E aqui criamos um arquivo de conflito vazio. Mais uma vez, vou copiar o comando. Coloque-o no terminal, e ele criará um pregador vazio RT JSON para mim, cada pregador de ferramentas e Eastland, requer um arquivo de configuração para entender o que queremos dessa ferramenta. E podemos ver todas essas opções de conflito para pregador dentro da documentação no link Opções. Se vamos aqui, veremos diferentes opções aqui que podemos usar a imagem interna RC Jason, por exemplo, tab com. Então, vou usar a largura da guia daqui. Só vou copiá-lo, colocá-lo dentro da configuração. E podemos ver que o padrão é dois. Então deixe-me colocar 10 aqui e vamos ver o que vai acontecer. Salvei o arquivo. Volto para testar o MGS. Pressiono Control S para salvar o arquivo. E boom, você vê que o recuo mudou. Agora. Ele usa a largura da torneira de 10 linhas vazias. Você provavelmente está pensando como é automaticamente como formatar esse arquivo. O problema é que o que acabamos de instalar dentro do nosso projeto sob dependências de desenvolvimento, instalamos o pregador como uma ferramenta, mas fora da formatação, como vemos, recurso está disponível através do VS Code extensão que você já deveria ter instalado até agora. Se você não fez isso, vá para a guia Extensões. Procure pregar aqui. Esta é a extensão e instale-a e verifique se ela já está configurada. Se você não fez isso, para assistir ao vídeo VS Code Configuration de projeto para projeto, você deseja reutilizar o pregador. Você não quer sempre especificar opções diferentes aqui. Confie em mim, haverá apenas alguns. Então, por esse motivo, vou compartilhar com vocês esse presente e você poderá simplesmente copiar e colar conflito de pregador que eu uso em todos os lugares. Então deixe-me colocá-lo aqui e deixe-me salvar o arquivo. Como você pode ver, eu uso cinco comandos e isso é suficiente para que um pregador funcione. Você pode ver se eu vou salvá-lo. Ele usa esse conflito agora. Incrível. Então, respondendo à pergunta, por que precisamos de pregador? Primeiro de tudo, você precisa entender que o pregador é uma ferramenta opcional, mas é altamente recomendável que você tenha pregador dentro do seu projeto JavaScript. A razão para isso é porque queríamos tornar nosso código o mais legível e sustentável possível. E o pregador nos ajudará com isso. Qual deles você prefere? Essa formatação estranha? Porque por algum motivo você não terminou o recuo manual ou prefere um código muito limpo alcançado com o pregador? Acho que será a segunda opção. Por fim, considere uma situação em que você tem muitos arquivos dentro do projeto e eles não estão formatados. Pregador. Então, o que fazer neste caso? Bem, a primeira opção é, claro, ir para todos os arquivos, pressionar Control S para salvar cada arquivo manualmente e, em seguida, o pregador se formará neles. Mas isso não é muito conveniente. Seria melhor criar um script que formate todos os nossos arquivos de uma só vez. E esse script usaremos pregador, e é aqui que entram os scripts NPM. Vamos criar um script NPM que usará o pregador para formatar todos os nossos arquivos dentro do projeto usando o pregador RC JSON. Então, se voltarmos à documentação do pregador, vamos para a página de instalação. Vamos rolar para baixo e aqui podemos ver agora formatar todos os arquivos com pregador e temos esse comando e px pregador dash, traço ponto direito. Deixe-me copiá-lo. E vamos voltar para os scripts do NPM. Então, aqui vamos definir e você o script NPM que vamos nomear o formato. Dentro desse roteiro, vou colocar n px, pregador, traço, ponto direito. No entanto, nós realmente não precisamos e Px aqui, você pode ler o que é n px neste alerta amarelo. Temos certeza? Então n px é basicamente uma ferramenta que é fornecida sem JS que permite executar pacotes diretamente do registro NPM sem instalação. Se eu não instalei o pregador e então usaria n px pregador dash, dash Reidar. Funcionaria porque o NP x usará pregador sem instalação diretamente do registro do NPM, mas não precisamos dele. Temos pregador instalado. E quando escrevemos pregador aqui dentro do script NPM, ele usará o pregador instalado dentro dos módulos de nó. Vamos experimentar esse comando que acabamos de definir. Vou voltar ao meu terminal e executarei o formato npm run. Você verá que algo está acontecendo. E agora alguns arquivos são afetados, basicamente todos eles. Vamos sacudi-los. Portanto, temos esse arquivo formatado, esse arquivo formatado, esse arquivo formatado. Então, basicamente, tudo agora está formatado usando um pregador. Vamos voltar ao pregador RC Jason, e talvez vamos mudá-lo para 10 tablets. E vamos executar novamente o comando npm run format. E você verá que todos os arquivos agora estão formatados contra o conflito de pregadores que acabamos de definir. É isso. Agora você sabe o que o pregador faz e por que precisamos dele? Vamos resumir rapidamente. Preacher é uma ferramenta que formatará arquivos dentro do nosso projeto atual, mais bonito tem um arquivo de configuração que é pregador de pontos RC JSON. Podemos usar o pregador por meio dos scripts NPM ou podemos usar o pregador por meio da extensão VS Code que instalamos. Então essa extensão, a única coisa que faz, só nos permite formatar arquivos. Quando apertamos o botão Salvar, se quisermos desativar essa extensão ou se não a tivermos, o pregador não se formará em nossos arquivos quando clicarmos em Salvar, a única oportunidade para formatar o os arquivos serão através do nosso script NPM personalizado, que nomeamos formato. Mas com a extensão, é muito, muito mais conveniente. Agora, vamos passar para ES lint antes de saltarmos para Eastland, deixe-me voltar rapidamente à nossa configuração anterior aqui e executar novamente o comando format. Incrível. Agora, o que é Eastland? Eastland também é uma ferramenta opcional que nos permitirá verificar o JavaScript em relação a alguns problemas comuns, relação a algumas diretrizes de código predefinidas. Precisaremos do ES lint para verificar se não temos erros muito simples em nosso código, como variáveis indefinidas, variáveis não utilizadas, ou talvez tenhamos algum pedaço de código que é usado forma errada e ES lint irá deixe-nos saber sobre isso. Então, novamente, assim como com pressão, vamos ao Google e vamos procurar o ES lint. Vamos clicar aqui. Você pode ver que o ES lint é linear. Então, linear é uma ferramenta que realmente verifica o código contra erros. Vamos clicar em Começar e, novamente, basta seguir a documentação. Então npm instale ES lint save-dev, copy. Vamos colocá-lo no terminal novamente. Dash, dash save dev flag garantirá que o ES lint será instalado como uma dependência de desenvolvedor no pacote Jason, novamente, dependências de desenvolvimento de água, dependências de desenvolvimento são as ferramentas que usamos no desenvolvimento ambiente. Eles não fazem parte do código-fonte. Então, se eu vou remover a Islândia e o pregador, meu projeto ainda poderá ser executado. Ótimo. Temos ES lint instalado. Agora vamos seguir a documentação. Então, ele nos sugere usar o comando init para inicializar o arquivo de configuração. Então, em vez disso, vamos criá-lo manualmente. Então, vou criar um novo arquivo aqui, e vou nomeá-lo ponto ES lint RC. Então esse será meu arquivo de configuração do ES lint. Para configurar o ES lint, temos que seguir exatamente o mesmo padrão que com o pregador. Você tem que criar um arquivo de configuração e temos que colocar alguns comandos para permitir Yes Lint entenda o que queremos dele. Vamos voltar ao site e aqui temos configuração. Então, vamos apenas copiá-lo. Mas vamos mudar algumas opções aqui. Vou colocá-lo aqui. Vou remover isso e acabamos com a seção de regras. Dentro da seção de regras na Islândia, RC, definimos regras ES lint que gostaríamos de usar dentro do nosso projeto contra o qual nosso código será verificado. Por exemplo, posso digitar uma regra chamada vírus não usado, e precisamos fornecer algumas opções aqui. E você pode ver isso até me dá editor de preenchimento automático desligado e desgastado. Então, o que são esses? Então, se eu vou adiar, essa regra será desativada e meu código não será verificado em relação a essa regra. Se eu vou colocar como uma opção para alguma regra de lint ES. Isso significa que quando eu for contra essa regra, ES fiapos me dará um aviso. E eu tenho uma terceira opção, que é erro. Isso significa que sempre que eu for contra essa função, Sim, o Lint produzirá um erro. Então, há algumas, digamos, regras cruciais que eu quero ser relatadas para mim como outra. E há algumas regras menores que eu quero ser relatada para mim como avisos. Podemos encontrar todas essas regras dentro da documentação. Eu sempre sugiro que você olhe dentro da documentação. Você pode encontrar tudo lá para que você possa até ver as opções de erro de advertência aqui, exatamente o que é dito para você. Agora, podemos ir ao Guia do Usuário e podemos seguir as regras. Esta é uma referência de regras. Você sempre pode encontrar todas as regras aqui. Por exemplo, se eu vou procurar barras não utilizadas, você pode vê-lo aqui. Vamos procurá-lo. Sim, não permita variáveis não utilizadas. Então é isso que a regra faz, é isso que permite o uso de variáveis não utilizadas. Então, vamos experimentá-lo. Vou voltar ao meu código. E aqui o que eu tenho erro de análise, a entrada da chave é reservada. Bem, sim, primeiro precisamos deixar o ES lint entender que estamos usando a sintaxe JavaScript mais recente. Para fazer isso, vamos ao ES fiapos. Aqui, adicionamos outra opção que será opções de analisador. Então, dentro das opções do analisador, temos que fornecer a versão AVMA. E vamos colocar 2020 aqui quando eu salvar o arquivo e voltar a testar o MGS, e vejo outro erro dizendo que importação e exportação podem aparecer apenas no módulo do tipo fonte proveniente do ES lint novamente. Então eu volto para yes Lind e posso fornecer outra opção aqui será o tipo de origem, o grau do módulo. Agora não temos nenhum erro ou avisos, então não temos uma regra de vírus não utilizada definida que produzirá um erro sempre que formos contra isso, é verdade, Vamos testar mgs. E aqui vamos criar uma variável de uso final. Talvez eu dê o nome de Olá. E o que vemos aqui? Vemos que ele é destacado com linha vermelha. Se eu passar o mouse, você verá o quão baixo é atribuído um valor, mas nunca usado. E vem, como você pode ver ES lint, nenhuma variável não utilizada. Se eu for voltar ao ES lint RC, e se eu for desabilitar essa regra, desabilite a verificação contra essa regra. Você verá agora, eu não tenho nenhum aviso ou um somador. Então, vamos voltar aqui e vamos colocá-lo como um aviso. E podemos ver que é amarelo porque é um aviso agora. E se eu colocá-lo de volta, ele ficará vermelho. Incrível. Talvez vamos manter um aviso e vamos voltar à documentação. Então, vamos voltar para a página de instalação. E aqui podemos ver na parte inferior que também podemos colocar a opção de extensões dentro do ES fiapos. O problema é que o ES lint tem muitas regras diferentes e escreve todas essas regras manualmente aqui o tempo todo. Isso não é muito conveniente porque nosso ES fiapos nosso vai ser bonito, muito longo. Isso não é conveniente. Então, para resolver esse problema, ES lint tem arquivos de configuração ou digamos que conflitos predefinidos que podemos estender do ES lint vêm incorporados no conflito recomendado pelo ES lint. Então, vamos apenas copiá-lo e colocá-lo no topo. Agora, usamos o condenado recomendado. Se voltarmos a testar o MGS, veremos que temos console não está definido agora. Bem, isso ocorre porque o ES lint coisas que estamos executando dentro do ambiente do navegador. E para isso, temos que especificar novamente que estamos correndo dentro do jazz. Então, para isso, temos que colocar as opções ENV aqui e especificamos que estamos dentro. Nota. E vamos dizer verdade, podemos realmente colocar muitas opções diferentes, como ES6, para especificar novamente que estamos usando a sintaxe JavaScript mais recente. E há muitas opções diferentes. E acredite em mim, você não precisa conhecer todos eles. Porque você sempre tem primeira documentação que você pode usar sempre que tiver problemas com a compreensão da Eastland ou pode simplesmente copiar e colar sim. Vincule conflitos de algum lugar e ajustado para suas necessidades. Este é muito básico. Vamos mantê-lo como está. Uma nota importante que eu queria enfatizar é que você só pode ver amarelo pairando ou talvez você possa ver esse vermelho pairando por aqui. Quero dizer, relatórios diretos dentro do VS Code, graças à extensão. Então eu tenho a extensão ES lint instalada. Aquele que integra ES lint ao código VS. É por isso que aqui vejo esta linha vermelha. Se essa extensão fosse desativada , o ES lint não me reportaria, assim como eu a vejo agora. Não ficaria vermelho. A única maneira que eu saberia sobre esse erro seria executar o comando ES lint, assim como fizemos antes com o pregador. Então, talvez vamos criar outro script NPM e vamos definir o comando para Eastland. Vamos voltar para package.json. Aqui eu vou colocar pode ser comando lint e vou chamar ES lint asterix dot JS ou como temos extensão MGS vou colocar e gs aqui, vamos executar para ES lint contra todos os arquivos com a extensão MGS. Vamos para o terminal integrado e vamos executar o script que definimos, npm run lint, e você verá o ES lint relata um problema. Olá recebe um valor, mas nunca é usado. Portanto, isso é muito conveniente porque no código de produção, aparentemente não queremos ter e usar variáveis. E há muitos erros e avisos diferentes que podemos receber. Mas acredite em mim, isso é para nosso próprio bem. Es lint nos ajudará a manter nossa base de código com menos erros quanto possível. Vamos utilizar muito o ES lint combinado com o pregador. No entanto, há um problema com ES fiapos e preacher. O problema é que algumas regras de pregador se sobrepõem às regras do ES lint. E para corrigir esse erro, precisamos navegar até ES lint. Se formos ao ES lint rolamos para o resumo aqui, podemos ver usar o pregador do condenado do ES lint para fazer o pregador e o link ES funcionarem bem juntos. Vamos navegar até o pregador de conflito enxuto ES. E vamos para a parte de instalação. Vamos copiá-lo. Vamos colocá-lo aqui. E novamente, dash, dash, save dev flag para instalar esse pacote como uma dependência de desenvolvimento. Se você vai olhar dentro das dependências de desenvolvimento, verá pregador de conflitos orientais agora. E vamos ver o que temos que fazer no pregador para a extensa matriz em seu arquivo Eastland RC. Então, estende algumas outras configurações e pressão. Tudo bem, então vamos colocar, vamos copiar o pregador. Vamos voltar para o ES lint estende-se. E você pode ver pelo exemplo que ele usa uma matriz. Portanto, o ES lint suporta ambos. Vamos transformá-lo em uma matriz. E vamos colocar o pregador aqui. Bom. Sem esse pacote, sem esse pregador condenado da ESPN, você acabará em uma situação em que você terá erros de Eastland e você não entenderá por que você os está tendo. Este pacote garante que você não tenha conflitos. E vou ver que é isso. Isso é tudo o que eu queria contar sobre ES fiapos e pregador para resumir rapidamente, o que é Eastland? Eastland é uma ferramenta que nos permitirá verificar nosso código, nosso código JavaScript, em relação algumas diretrizes comuns predefinidas. Ele acabará por tornar nosso código menos propenso a erros, e garantirá que nossa base de código, o mais limpa possível. Preacher formatará nossa base de código para que ela se torne o mais legível possível. Só mais uma vez, vou dizer que essas ferramentas são opcionais, mas você verá pregador e ES lint em quase todos os projetos JavaScript porque as pessoas querem que seus projetos sejam legíveis e ser menos propenso a erros. É isso. Vejo você no próximo. 19. O que são Server, JSON, API RESTOS e GraphQL?: Ei, neste vídeo, eu gostaria de falar sobre servidores. O que é um servidor? O que é uma API? O que é uma API rest? O que é o GraphQL? Vamos descobrir isso juntos. Primeiro, vamos começar com o servidor. O que é um servidor? Um servidor, é apenas um computador em algum lugar na Internet. Ele executa algum software. E esse software nessas aulas de computador para nossas solicitações recebidas. Por exemplo, quando eu navego para qualquer site, quando clico nesse link, meu navegador envia uma solicitação para esse servidor. Então, à esquerda, este é o meu navegador, e ele envia essa solicitação para esse servidor. Este servidor lida com a solicitação recebida e envia de volta arquivos HTML, CSS e JavaScript. Então, novamente, um servidor, é apenas um computador que executa algum software que de alguma forma lida com nossas solicitações recebidas e envia uma resposta de volta. Agora, e se eu não quiser receber sempre arquivos HTML, CSS e JavaScript, talvez eu só queira executar alguma consulta no site, como na barra de pesquisa. Preciso retornar HTML novamente? Não, você não sabe. Você só precisa obter os dados, o resultado dessa consulta na barra de pesquisa. Portanto, nesse caso, os dados devem ser transferidos em algum outro formato. Portanto, algum outro formato geralmente é formato JSON ou formato XML. Mas o XML já está obsoleto, eu diria na web agora, todos usam o JSON. Então, vamos procurar JSON ou talvez até mesmo pela API de rest falsa gratuita de espaço reservado JSON . Tudo bem, então primeiro precisamos descobrir o que é JSON. Só vou clicar em Executar script aqui. E recebo que este JSON é apenas o formato no qual os dados são transferidos pela Web. Ele pode ser usado não apenas na web, mas em qualquer outro cenário. É muito fácil transferir informações neste formato. Parece muito semelhante a um objeto JavaScript. Agora, vamos voltar à nossa tela. Então, como ele se encaixa nesse cenário? Então imagine que estou aqui no site e digito algo na barra de pesquisa, que está dentro do site. E eu quero recuperar meus resultados de pesquisa no formato JSON, eu enviaria outra solicitação para esse servidor, e esse servidor tratará minha solicitação, minha consulta. Ele procurará o banco de dados. Ele recuperará os resultados e enviará esses dados de volta para mim no formato JSON, que se parece exatamente com isso. Portanto, não há necessidade de HTML, CSS ou JavaScript. Portanto, esse tipo de servidor que hospeda arquivos HTML, CSS e JavaScript, geralmente chamados de serviços de hospedagem. Então, eles são usados para hospedar páginas HTML básicas. Eles apenas colocam seus arquivos, HTML e CSS em sua máquina, e eles apenas servem esses arquivos no computador. É isso. E quanto aos servidores de API? Então, o que é uma API, em primeiro lugar, API significa interface de programação de aplicativos, e geralmente serve para servidores de API apenas porque, na maioria das vezes, os servidores de API servem a esse propósito de intermediário entre você e banco de dados subjacente. Mas esse não é apenas o caso. Bem, eles geralmente são chamados servidores de API porque são interfaces para tudo o que está por trás desse servidor. É por isso que eles são chamados de APIs ou interfaces ou o que ele os chamou. Vamos dar uma olhada neste espaço reservado JSON mais uma vez. Então eu envio uma solicitação para este URL. Só vou copiá-lo e colocá-lo aqui. Se eu acessá-lo, você provavelmente verá isso em formato bruto assim. Este servidor atua como uma API rest porque segue o formato restante. Portanto, é uma API porque é uma implementação de servidor personalizada. Portanto, é aquele software personalizado instalado no servidor que lida com minha solicitação para ele e envia de volta Jason, essa é a parte da API. Agora, o que é descanso? Descanso significa que ele segue o padrão de design restante na implementação do resto. Isso significa que o código do tipo de espaço reservado JSON do servidor que calma expõe vários endpoints que podemos acessar para recuperar dados. Por exemplo. Vá para a barra para fazer a barra um. Este é todo id. Obtemos dados relacionados com o ID número 1. Se eu digitar sete aqui, você verá que agora tenho id de usuário um, id sete e dados diferentes. Se for quatro, serão dados diferentes. Se for algo assim, você não verá nada porque ele não existe o servidor API deles, este que estamos acessando agora é, na verdade uma API para o banco de dados subjacente que ele usa sob o capô. Certo, e segue o padrão de descanso. Você pode navegar até o site principal aqui. E você pode procurar outros pontos finais disponíveis nesse recurso. Por exemplo, você pode ver os recursos aqui. Podemos ir para postagens, podemos ir aos usuários, podemos ir para álbuns. E você pode ver que todos eles têm endpoints diferentes. Novamente, isso ocorre porque segue a implementação do resto. Imagine uma casa grande com muitas portas. Então, uma casa grande é o servidor, o servidor API. E essas portas são e pontos que você está acessando para obter dados. E esses dados são transferidos no formato JSON. Porque é muito simples entender esse formato. É muito leve e fácil de ler ou escrever, mas o resto não é a única implementação de servidor que pode existir na natureza. Há outro realmente popular agora, que é chamado GraphQL. E, obviamente, existem os outros. Então, mas agora no momento, principalmente dois tipos, API rest e GraphQL API. Graphql é ao mesmo tempo uma linguagem e, ao mesmo tempo a implementação do servidor, a arquitetura. Então, vamos procurar o GraphQL no Google ou talvez o GraphQL Explorer. Isso nos levará a esta página de documentos do GitHub GraphQL API. E vai, vamos acabar nessa página. Isso exigirá que eu faça login para usá-lo. Então, vou entrar com minha conta. Se você não tem a conta do GitHub por enquanto, tudo bem. Basta olhar o vídeo. Portanto, esta é a linguagem GraphQL. É assim que se parece. Para solicitar dados do servidor GraphQL, temos que enviar uma co-variação como o pai nesse formato seguindo a linguagem QL do gráfico. Então, se eu vou enviá-lo, você verá que eu recebo dados neste formato e ele é o formato JSON, como você pode ver. Então, qual é a diferença entre gráfico e repouso? Bem, antes de tudo, como mencionei antes, API rest tem vários endpoints. Por exemplo, barra todos. Onde está isso? Corte comentários, álbuns, fotos e tarefas. Para acessar dados, seu URL deve ser diferente para acessar recursos diferentes. Mas o GraphQL, é um pouco diferente. Se eu clicar em Inspecionar e ir para a guia Rede aqui, quando eu pressionar este botão de reprodução, você poderá ver o URL que está sendo acessado, que é barra do proxy de barra GraphQL. E se eu executar outra solicitação, o URL não será alterado. Bem, a implementação do servidor GraphQL tem apenas um ponto final através qual todas as solicitações passam para entender o que o usuário recusou, o que queremos do servidor. Enviamos essa covariação para o servidor. Se, por exemplo, navegarmos para referências e consultas em uma nova guia. Então, vamos procurar o usuário e ele espera um argumento. Vamos tentar essa consulta. Então, vou remover tudo isso. Vou digitar usuário, como diz aqui. E precisamos fornecer um argumento. Você fornece um argumento. Temos que abrir parênteses e colocamos esse argumento aqui. Login é o argumento do tipo string. Vamos colocar meu apelido aqui. Agora, em colchetes encaracolados, tem que especificar que tipo de dados temos que receber. Então, ele vai ser login. Se eu colocá-lo assim. Bem, eu basicamente tenho a mesma informação, mas a consulta é diferente e nesse ponto é a mesma. Agora, você já viu a diferença? Bem, a diferença, a principal diferença sobre o GraphQL e a API rest é que o GraphQL só envia dados que você pede, certo? Então, aqui eu peço apenas login na minha consulta. Portanto, essa consulta é chamada de esquema, esquema que você solicita do servidor. Tudo bem, então eu solicito esse esquema de apenas login e recebo apenas login de volta à API rest. Se formos a posts, pedi postagens. Não especifico quais campos quero recuperar da pose. Isso cabe ao servidor decidir para que o servidor centralize o título e o corpo, e não podemos alterar isso. Tudo bem, se eu acessar postagens com esse ID, ele me dá título e corpo. Mas com o GraphQL, posso especificar quais campos quero recuperar do servidor se navegarmos até os cães. Então, faça login, na verdade, essa consulta nos retorna usuário do tipo. Se abrirmos, o usuário tem muitos campos e podemos realmente usar a inteligência do GraphQL. Então, vou pressionar o espaço de controle. E aqui eu tenho espaço de controle biológico aqui talvez tenha nome aqui que eu tenha login. Então você pode ver que estou usando o idioma de consulta para especificar qual campo eu quero recuperar. E quando eu pressiono Play para enviar a consulta, você pode ver agora que tenho minha forma de dados personalizada especificada na consulta. Muito legal. Então, essa é a principal diferença. E você provavelmente pensará que o GraphQL é, Oh meu Deus, é incrível. Por que precisamos de APIs de descanso? O problema é tudo sobre implementação e sua complexidade. Graphql foi criado pelo Facebook alguns anos e tornou-se muito popular. No entanto, a API rest é uma solução mais madura e testada em batalha. Graphql é difícil. Não é tão fácil. É fácil consumir o Graph kill, mas para implementar o GraphQL, requer um bom conhecimento. A API Rest é mais simples, mais fácil de implementar e é mais intuitiva em comparação com parabéns do GraphQL. Agora você sabe o que é uma API. Vejo você no próximo. 20. VS de lados de clientes Renderização de lados do servidor (dinâmico e estático): Ei, neste vídeo, gostaria de falar sobre aplicativos do lado do cliente e do lado do servidor. Por que nos importamos e por que é importante entender a diferença? Vamos primeiro. Deixe-me abrir minha pequena tela que preparei. No topo, temos três tipos principais de renderização na web. A primeira é a renderização no lado do servidor, que é um roteamento no lado do servidor. Em seguida, temos renderização no lado do cliente, que usa o roteamento do lado do cliente. E então temos uma abordagem híbrida, que combina ambos. A melhor maneira de entender a diferença entre esses três é observar os exemplos. E isso é exatamente o que vamos fazer. Se eu for ao navegador aqui, preparei dois sites, site steam e o Netlify. Ambos são aplicativos de renderização no lado do servidor. E como sabemos sobre isso? Se clicarmos com o botão direito do mouse na página e acessarmos a fonte da página, aqui, podemos ver a marcação. Portanto, se virmos a marcação na origem da página, isso significa que a página é renderização no lado do servidor. Então isso é o que você vê aqui, foi retornado do servidor quando eu acesso esse URL. Além disso, cada página contém ataques met exclusivos. Isso significa que se eu for para uma página diferente e se eu inspecionar a origem da página dessa página, as metatags serão diferentes e a marcação será exclusiva para cada página no site. Agora, temos um segundo exemplo, Netlify. Ele também usa renderização no lado do servidor. Se eu inspecionar a página, tenho exatamente a mesma imagem. Tenho metatags exclusivas e tenho a marcação. Tudo bem? Mas Netlify é diferente. O problema é que o Netlify usa páginas estáticas ou renderização estática no lado do servidor, enquanto o steam usa renderização dinâmica no lado do servidor, qual é a diferença? A diferença é que, no caso da Netlify, todas essas páginas são apenas estáticas, elas não mudam. Isso também significa que todas as páginas do site da Netlify têm seu próprio arquivo HTML. Se eu for para a página de preços, a página de preços tem seu próprio arquivo HTML, assim como a página inicial ou qualquer outra página. Agora, e o vapor? Vapor, um pouco diferente. Ele usa renderização dinâmica no lado do servidor. Isso significa que esta página, por exemplo, página do jogo, esta é apenas uma página de esqueleto. Ele tem o modelo que ele usa para renderizar jogos. Então, se eu for para qualquer outra página, você pode ver que ela parece exatamente a mesma. A única coisa que foi alterada são as informações na página, mas o layout é o mesmo. E esse layout é o esqueleto usado para inserir dados dinamicamente nesse esqueleto. E isso é exatamente o que o vapor está fazendo. Então, para todas essas páginas de jogos, eles têm apenas um esqueleto. E esse esqueleto é reutilizado para inserir os dados dinamicamente. Ele é chamado de dinâmico porque toda vez eu envio uma solicitação para acessar essa página, o servidor cria dinamicamente marcação HTML e, em seguida, ele me envia de volta para recusar. É por isso que cada página cada página é diferente. Ele tem marcação exclusiva porque foi criado ou montado dinamicamente no servidor. Ao contrário das páginas estáticas, marcação HTML não é montada no momento da solicitação quando eu acesso esta página. marcação foi montada quando o aplicativo foi construído. Então, ele foi criado uma vez e agora toda vez que eu acesso essa página de preços, ele apenas envia a marcação estática porque ela não tende a mudar. Tudo bem, a desvantagem das páginas estáticas é que se precisarmos alterar algo em nosso conteúdo estático, temos que reconstruir o aplicativo, regenerar páginas HTML e depois carregá-las para hospedagem novamente. Então, agora eles são considerados atualizados. Com a renderização no lado do servidor, esse não é o caso. Você tem o esqueleto e os dados são inseridos dinamicamente. Isso significa que os dados recuperados do banco de dados e, em seguida, com base nesses dados, o HTML é retornado. Você não precisa mudar nada. Você não precisa regenerar páginas ou fazer nada. Somente se você precisar alterar o layout ou o esqueleto. Somente neste caso, ele deve ser reimplantado para refletir todas as alterações nesse esqueleto. Vamos para o segundo tipo, que é renderização do lado do cliente, ou mais frequentemente chamados de aplicativos de página única como PA. Agora, quais são esses sites? Aqui eu também preparei dois exemplos. Telegram, versão web. E este site instantâneo que foi construído com o React a propósito. Então, se eu inspecionar o telegrama, Exibir fonte da página, posso ver que não tenho nada aqui. Se eu for para o body tag, está totalmente vazio. No entanto, se eu inspecionar elementos da página, a marcação estará lá. Então, o que está acontecendo aqui? Do servidor? Eu recebo esse arquivo HTML de urso apenas com pacotes JavaScript. E JavaScript é aquele que renderizará minha página, quem criará a marcação? Quem criará o HTML dentro do navegador. É por isso que ele é chamado de renderização do lado do cliente, porque o JavaScript é aquele que renderizará a página dentro do navegador assim que tivermos esse HTML do servidor, essa é a diferença. Portanto, na renderização do lado do servidor, já temos marcação montada e retornada do servidor antecipadamente. Mas com aplicativos de página única ou com renderização no lado do cliente, não temos isso. Temos um mínimo de HTML muito simples e o restante é montado dentro do navegador por JavaScript. É isso. Mas há uma desvantagem muito crucial sobre aplicativos de página única ou renderização no lado do cliente. É ruim para SEO, que significa otimização de mecanismos de busca. O problema é que, se você quiser que esta página seja classificada e rastreada pelo Google ou pelo Facebook, é sempre melhor renderizar no lado do servidor. Porque os rastreadores, o que o mar, eles vêem exatamente isso, esta página fonte. Eles vêem a marcação, eles veem ataques de Matt. E com base nessa marcação e nas metatags, eles podem executar e entender o que é essa página. No entanto, mas aplicativos de página única, rastreadores, eles não vêem nenhum desses. Eles não esperam que o JavaScript no navegador monte e renderize a página. Eles só vêem essa tag de corpo vazio e esses ataques matemáticos básicos. Então, se você precisar de um bom SEO, use renderização no lado do servidor. Tudo bem, agora temos esse conceito de roteamento no lado do servidor e roteamento do lado do cliente. O que são esses? E aplicativo de página única. Você pode ver que, se eu navegar pelas páginas, a URL muda, mas minha página, ela não será atualizada. Isso é chamado de roteamento do lado do cliente porque foi tratado no cliente por JavaScript. Isso significa que o JavaScript é aquele que altera o URL. Javascript é quem renderiza a página. Certo? Ele não envia solicitações adicionais para o servidor. Tudo é feito dentro do navegador. Ao contrário do roteamento do lado do servidor, se eu for para qualquer outra página, você pode ver que ela está sendo atualizada porque o que eu faço basicamente, peço ao servidor que me forneça esta página. E essa é a diferença. Portanto, o roteamento do lado do servidor é quando você envia outra solicitação para o servidor e solicita esta página com aplicativos de página única com roteamento do lado do cliente. Tudo isso é feito dentro do navegador sem solicitações adicionais. Certo, ótimo. Agora, a terceira forma de renderização é chamada de abordagem híbrida. A abordagem híbrida é a melhor de dois mundos serem combinados. Temos renderização no lado do servidor e temos navegação no lado do cliente, roteamento do lado do cliente. Agora, um exemplo seria a documentação do Netlify. Então, se eu inspecionar a origem da página, posso ver a marcação e posso ver ataques conhecidos exclusivos. Muito legal. Mas se eu tentar navegar para qualquer outra página, você poderá ver as alterações no URL. No entanto, a página não atualiza. Assim, na primeira solicitação, quando você acessa este site inicialmente assim, ele enviará marcação já montada do servidor para você, o que significa que é renderização no lado do servidor. No entanto, depois disso, uma vez que a página é carregada, o JavaScript assume o controle e você terá essa sensação de gostar no aplicativo ao navegar na página da Web. Muito legal, certo? Então, no momento presente, a abordagem híbrida é muito, muito popular porque, novamente, combina o melhor de dois mundos. Você pode ter uma boa otimização de SEO devido à renderização no lado do servidor, e você pode ter um aplicativo como se sinta com o roteamento do lado do cliente. Muito legal. Agora, quais são os contras e prós de cada abordagem? Então eu já mencionei isso, mas vou fazer isso de novo. O primeiro é o C0, que significa otimização de mecanismos de busca com renderização no lado do servidor, o COO é o melhor resultado porque você já significou ataques montados. Você já tem o conteúdo da página montado na marcação. E com base nessas informações, rastreadores, como rastreador do Google, Facebook, arrastões do Twitter e outros trollers. Eles podem analisar sua página com base nessas informações e classificar sua página adequadamente com aplicativos de página única. Este não é o caso. Se eu inspecionar a página, só consigo ver o mínimo muito nu. No entanto, existe uma solução moderna para resolver esse problema de aplicativos de página única. E a solução é pré-renderizar o aplicativo de página única. Isso significa que cada página no aplicativo de página única no aplicativo do lado do cliente será pré-renderizada em um arquivo HTML estático. Então, cada página terá seu próprio HTML. E quando você acessa esta página, ela lhe trará, ela lhe dará o HTML estático que foi gerado. Isso é o que a Netlify faz. Netlify é um serviço de hospedagem e eles pré-renderizam aplicativos de página única para torná-los mais otimizados para SEO. Esta é uma ótima solução. Então, em seguida, temos um aplicativo como sentir. Portanto, os aplicativos de renderização no lado do servidor, ou mais especificamente, o roteamento do lado do servidor, não possuem esse recurso porque você pode ver sempre que navega, a página é atualizada e você instantaneamente entenda que este é um site. No entanto, com o roteamento do lado do cliente, você recebe um aplicativo como sensação porque a página não é atualizada, assim como estamos navegando no aplicativo móvel. E o último ponto é, requer JS, aplicativo renderizado no lado do servidor ou mais especificamente, páginas estáticas. Eles podem não significar JavaScript. Pode ser um conteúdo estático apenas com HTML e CSS, que não precisa de JavaScript. Mas aplicativos de página única ou aplicativos do lado do cliente sempre precisam de JavaScript porque tudo é feito pelo JavaScript. É como o núcleo dos aplicativos do lado do cliente. E se você desativar o JavaScript ou se ele não estiver disponível por algum motivo do que a apple simplesmente não funciona no treinamento. Vamos nos direcionar para criar aplicativos de página única com o React. Espero que tenha sido claro e te vejo no próximo. 21. Atalhos de código VS: Oi. Neste vídeo eu vou mostrar meus atalhos que eu uso no código V s. Isso será útil para todos. Não se concentre no frio agora. Este vídeo é sobre atalhos. Começamos abrindo uma pasta de projeto para esse controle de espera que pressione K mais o, em seguida, selecione a pasta para abrir. E nós somos perspicácia. Agora precisamos de terminal para isso. Você pode pressionar o controle, além de inclinado ou controle mais J T aberto em riso muito terminal entre esconder e mostrar controle de imprensa Estado mais Jay, Há muitas situações em que precisamos mover linhas de código ao redor para que basta segurar para fora e pressione setas picadas e inferiores ela moveu linhas Cordis apontando Seja, então precisamos gerenciar várias abas abertas para abrir arquivo em uma nova guia. Basta abrir esse arquivo a partir do Explorer ou pressione o controle mais B para barra Riesco Charge, Em seguida, procure o arquivo e pressione enter para alternar entre guias. Segure e pressione números de 1 a 9. Ela abriu a torneira ordenada relevante a maior parte do tempo. Precisamos adicioná-lo. Algo em várias linhas. Seleção de várias linhas e ajude-nos a mover o curso ou para o lugar certo. Mantenha o controle, além de setas para cima e para baixo para estender a seleção com leões. Controle de liberação mais para fora e agora somos capazes de editar código no modo multi linha, segure, deslocamento e pressione prados para seleção de único caractere foram segurar controle e pressionar setas para mover carros ou para as palavras seguintes ou anteriores. Você pode combinar turno e cultural para selecionar toda a ala. Também podemos selecionar correspondência específica para edição de várias linhas, mover o seu curso ou para a ala ou selecionar alguns personagens, manter o controle e pressionar D. Uma vez ele irá selecionar o tribunal atual, em seguida, manter o controle e Presidente de Ele irá adicionar ocorrências para a seleção que correspondem ao padrão. Também podemos criar várias abas para facilitar o controle de imprensa, além de barra invertida para dividir este coreano em vários toques. Na verdade, o mesmo pode ser aplicado ao terminal dentro do controle de pressão do terminal mais barra invertida para abrir várias instâncias. Isso que entre instâncias segurar e pressione a seta superior ou inferior e é isso. Estes são os principais atalhos que facilitarão o protesto do desenvolvimento. Você sempre pode personalizar configurações de carimbo Invesco estavam aqui em baixo. Vejo-te no próximo 22. Introdução ao JavaScript: Olá, Bem-vindo à seção JavaScript. Nesta seção, falaremos sobre recursos de sintaxe JavaScript mais comuns. Não abordaremos o básico, porque entenderemos tudo isso durante o processo, vamos anexar padrões mais avançados e mais comuns. Precisamos entender tudo isso para nos sentirmos confortáveis durante o desenvolvimento da criação. Espero que você goste. Vejo você no próximo. 23. Var VS Deixe VS Const: Oi, Neste vídeo, falaremos sobre diferentes tipos de variáveis que existem em JavaScript. Estes são var, let e const. Neste vídeo, entenderemos a diferença entre eles e qual tipo temos que usar nessa situação. Vamos. Então, como tudo isso vai ser organizado? Vou criar um único script que vou nomear o arquivo gs. E então vou executar esse script com exemplos através do terminal integrado usando o comando node file.js. Então bar, deixe e const. Qual é a diferença? Vamos talvez criar uma variável do tipo var e chamá-la de meu nome. Então eu vou apenas console.log essa variável. E então vamos executar o script. Você verá que Andrew é impresso, tudo funciona. Então, qual é o problema com essa variável? Eles lidam com var é que esse tipo de variável está incluído ao escopo de função mais próximo. Para entender que temos que criar essa variável dentro de uma função. Então, vamos criar uma função. Imprima meu nome. E dentro dessa função, vou colocar var. E então eu vou registrar meu nome no console. Agora, se eu vou executar o script, não te verei nada porque bem, é uma função e eu tenho que chamá-lo, imprimir meu nome. Ótimo. Agora execute o script novamente. Você verá Andrew, o resultado é o mesmo. Se eu vou colocar o log do console fora do escopo da função, receberei um erro de referência. Porque meu nome é definido dentro do escopo da função. Ele não é visível fora dele. É por isso que temos um erro de referência. Ótimo, entendemos isso. Mais uma vez, qual é o problema com var? Como um triste, ele está incluído ao escopo da função mais próximo. Isso significa que não importa quantos escopos eu tenho dentro dessa função, ela será visível em todos os lugares. O que quero dizer é que se eu vou colocar muitos, digamos, se blocos aqui, se cinco for maior que um, então eu vou criar outro no blog deles apenas para criar escopos, ok? Se 10 for menor que 20, se cinco for maior que três, não importa o que eu faço aqui. Eu só quero criar tantos escopos internos quanto possível. E agora o que vou fazer, vou colocar var, meu nome dentro do máximo em seu escopo, e então vou tentar acessar meu nome dentro dessa função. O que você acha que esse código entra em funcionamento conforme o esperado e veremos a entrada no terminal. Vamos experimentá-lo. Vou executar novamente o nó do script file.js. E vemos Andrew, bem, isso é imprevisível. Queremos que essa variável se comporte para não ser visível fora do escopo em que foi definida. Portanto, o escopo em que essa variável foi definida é esse bloco if mais interno, se ele foi definido, digamos que neste bloco, neste caso, ele ficaria visível em todos os lugares dentro, mas não fora dele. Var é novamente, está incluído no escopo da função mais próximo. Não importa onde ou em que, em seu escopo mais, defini variável do tipo var dentro de uma função, sua visibilidade sempre será escopo da função. E isso é ruim porque é imprevisível. Queremos sempre garantir que nossa variável esteja sempre visível somente dentro desse escopo onde ela foi definida aqui. Então, para corrigir esse problema, temos variáveis de tipo, let e const. Então, se eu vou colocar o LED aqui, e então vou tentar executar o script. Você verá um erro de referência. Porque agora let tem escopo para o escopo mais próximo, na verdade, para o escopo onde ele foi definido. E o mesmo com const. Se eu vou colocar const aqui e executar este script, você verá novamente a mesma coisa. Meu nome não está definido erro de referência. Então, para corrigir isso, para corrigir o erro de referência, temos que referenciar meu nome neste escopo onde ele está disponível, o que será esse. Vamos mover o log do console para esse escopo. E vamos tentar novamente. Você verá que a entrada é impressa. E agora isso é previsível porque sabemos que essa variável é definida dentro desse escopo e sua visibilidade termina sempre que saímos, se eu colocar o log do console nesse escopo, você verá novamente o erro de referência. Oh, deixe-me salvar o arquivo. Você verá um erro de referência porque isso sai do escopo. Onde meu nome está definido, certo? Esta é a diferença entre chumbo const e var let e const tipo de tigelas de fibra. visibilidade termina com o escopo envolvente, enquanto var termina com o escopo da função mais próximo. Então, se eu tiver outra função dentro de uma função, digamos que a função olá. E então vou definir a mesma coisa. Tudo isso dentro de Hello than var será visível somente dentro da função hello. Não será visível imprimir meu nome, mas sim para Hello. Tudo bem, acho que está claro. Agora, qual é a diferença entre let e const? Vamos esse tipo de variável que tende a ser reatribuída. Digamos que eu criei meu nome viável e, no futuro, quero reatribuí-lo. Talvez eu queira agora o valor não Andrew, mas outra coisa. Então, o que eu faria, eu reatribuiria esse valioso. Então, pelo nome, agora se torna john. E se eu for consolar o log John, você verá na verdade John não entrar porque agora ele tem um valor diferente. Vamos digitar que pode ser reatribuído. No entanto, com const, não é. Deixe-me salvá-lo e executar o script. Você verá atribuição para variável constante porque const significa constante, algo que não muda se eu criá-lo pelo dobro do meu nome e colocá-lo como entrada, significa que ela não mudará. Sempre será Andrew. Mais uma vez. Vamos pode ser reatribuído. Se você criou uma variável, meu nome e, no futuro, se tiver certeza de que vai renomeá-la, use lead porque o lead pode ser reatribuído se você não quiser que essa variável mude, Tem certeza de que qualquer valor que você atribuir a essa variável permanecerá assim. Use const. Na prática, a maioria das variáveis terá o tipo const. E essas variáveis que sabemos que vamos reatribuí-las. Vamos usar lat, mas de outra forma const, e nunca usamos var. Então, para resumir rapidamente, o fio é um tipo de dados de idável, que era a habilidade é o escopo de função mais próximo. Não importa como lá maioria definiria essa variável. Ele ainda estará visível no escopo da função. E, como let e const, let e const têm escopo para o escopo mais próximo onde estão definidos. Vamos esse tipo de variável que pode ser reatribuída e const é constante. Se você for criar uma variável constante, ela não será alterada mais tarde. No entanto, há mais um pequeno truque com const, e esse truque são objetos. Portanto, se Meu nome for um objeto, esse objeto pode ser modificado, mas você não pode alternar o tipo de objeto para outra coisa. O que quero dizer é que, se meu nome, eu o defino como um objeto e depois quero mudá-lo para John. Terei designação para uma batalha constante. Mas se eu quiser dizer, modifique o objeto em si, por exemplo, dê a ele uma nova chave. Por exemplo, meu nome ponto algo vai ser olá. E depois vou registrar meu nome no console. Você verá o objeto que tem uma chave, algo com valor Olá. Você tem que se lembrar disso. Portanto, neste caso, você não modifica diretamente por tipo duplo, mas modifica o objeto em si. Agora você sabe a diferença entre diferentes tipos de variáveis. Vou dizer isso mais uma vez. Na prática, a maioria de nossas variáveis será do tipo const. E para aquelas variáveis que tendem a mudar, vamos usar o tipo LED. Nunca usaremos VAR. Vejo você no próximo. 24. O que é Array?: Oi, Neste vídeo, vamos falar sobre o mapa de pontos da matriz. O método do mapa de pontos da matriz está disponível em todos os arrays JavaScript. Ele é usado para iterar sobre a matriz de elementos e é usado para transformar cada elemento de matriz em outra coisa. É por isso que o mapa de pontos da matriz de nomes. Vamos ver isso em um exemplo. Em file.js. Vou criar uma nova matriz, que vou nomear Olá e deixar ser 4326. Agora, digamos que eu queira iterar sobre esse array. Eu quero que você simplesmente registre o log de cada elemento de matriz. De um modo geral, posso conseguir isso com a maneira tradicional de fazer isso usando o loop for, mas agora podemos usar um mapa de radar. Então, vou colocar o mapa de pontos de saudação. E uma vez que eu abra o código VS do parêntese me dará a descrição. Você pode ver que o método do mapa de pontos recebe a função de retorno de chamada. E o segundo argumento é esse arco. Este arco é sobre o, esta palavra-chave em JavaScript. Não vamos tocar nisso. Estamos interessados em. A função de retorno de chamada. Callback é aquela função que está sendo passada como argumento para alguma outra função. Então, como vamos passar uma função para a função map, é por isso que a chamamos, ligue de volta. Tudo bem, acho que está claro que vamos usar muito o retorno da palavra. Então esse callback recebe três argumentos. O primeiro argumento é valor, depois temos índice e matriz. E vamos digitar a função. E se eu vou abrir parênteses novamente, verei valor, índice e matriz. Portanto, o valor é o valor do elemento atual. O problema é que o método do mapa de pontos itera sobre uma matriz. Portanto, esse retorno de chamada que passamos para o método do mapa de pontos será executado para cada elemento de matriz. Portanto, se tivermos quatro elementos no total nessa matriz, isso significa que essas funções de retorno de chamada serão executadas quatro vezes para cada elemento e valor da matriz. O primeiro argumento no callback será o valor atual que estamos iterando. Portanto, pela primeira vez que o callback será executado, o valor será, pela segunda vez, o valor será três, e assim por diante até o último elemento. O segundo argumento aqui é o índice, e será o índice do elemento de matriz atual. Então, para o primeiro elemento, será 0 porque os arrays em programação começam com índice 0. Então, será 0, 1, 2 e 3. Vamos chamá-lo de idx. E o terceiro argumento será o array. E será a mesma matriz para a qual aplicamos esse método de mapa de pontos. Então, vamos dizer que é, e eu vou dentro desse callback dentro dessa função. Vamos, na verdade, console.log, valor, índice e array. E agora vamos tentar executar o arquivo de nó de script HGS. E o que vemos, então primeiro vai o valor. Como você pode ver para três a seis, vemos todos os nossos elementos de matriz, o que está correto porque, novamente, esse callback é executado para todos os elementos da matriz. A segunda coluna que vemos é o índice desse elemento. Então, para tem índice 0, isso é o que você vê no terminal. E o último elemento terá índice três, porque, bem, este é o último elemento e sabemos que matrizes começam com índice 0, o que está correto. E o terceiro valor será a própria matriz na qual esse método de mapa de pontos foi aplicado. Mas esse não é o verdadeiro poder do método de plotagem de pontos. Ele é usado para transformar cada elemento de matriz em outra coisa. E eles tomaram o método do mapa produz um novo valor. Ela produz uma nova matriz. Isso significa que eu posso escrevê-lo em uma variável. Então, vou colocar o resultado const igual a hello.mat. E então eu posso realmente o resultado console.log para ver o que eu tenho. Se eu for executar esse script, terei uma matriz de quatro elementos em que cada elemento é indefinido. Por que é indefinido? Bem, o problema é que o método map espera que retornemos algum valor dessa função, desse retorno de chamada. E esse valor que retornamos será definido como um novo valor para o elemento atual. Por padrão, quando não retornamos nada de uma função, essa função retorna indefinida. É por isso que temos indefinido em todos os lugares. Vamos tentar colocar o retorno do retorno de chamada. Você consegue adivinhar qual será o valor? Vou executar esse script e agora ele vai ser 4, 4, 4, 4. Bem, novamente, essa função de retorno de chamada é executada para cada elemento de matriz. E para cada elemento de matriz, retornamos para, se eu vou colocar valor multiplicado por dois, você pode adivinhar o resultado agora? Vamos ver. Agora temos 864 e 12. Basicamente o que fizemos, apenas multiplicamos cada elemento de matriz por dois. Porque mais uma vez que o callback é executado para cada elemento de matriz. Pela primeira vez. Ele será executado para o primeiro elemento que é quatro, valor será para, valor será multiplicado por dois, retornamos oito, o que significa que no valor de retorno para o método map para o primeiro elemento, temos o valor 8. Isso é o que vemos. O mesmo vale para o segundo elemento. Esse callback é executado. O valor será 3. 3 multiplicado por 2 é 6 para o segundo elemento. Agora temos seis, e assim por diante até o último elemento. E é isso. Este é o mapa de pontos de matriz de palavras usado para, vamos utilizá-lo muito, especialmente no React, mas teremos que mapear algum array para reagir a marcação. É por isso que é muito importante entender o método do mapa. É isso. E eu vou te ver no próximo. 25. O que é Array?: Ei, neste vídeo vamos falar sobre uma redução redox, assim como uma redução de ponto de matriz de mapas de radar itera sobre elementos de uma matriz. No entanto, ele faz fundamentalmente uma coisa diferente se o mapa de pontos da matriz for usado para mapear cada elemento de matriz para algum outro valor, redução de pontos da matriz é usada para compactar ou reduzir todos os elementos da matriz em um único valor. Vamos ver isso em um exemplo. Se voltarmos ao Arquivo GS, vamos criar uma nova matriz aqui, olá, que será sete. 6945, talvez. Ótimo. Agora podemos usar o método de redução de pontos da mesma forma que usamos o método map, que significa que podemos digitar hello dot reduce. E assim como no mapa de pontos, temos que fornecer uma função de retorno de chamada. Mas desta vez, a função de retorno de chamada receberá argumentos diferentes. Portanto, temos valor anterior, valor atual, índice atual e array. Então, vamos tentar ver o que eles são. Então, fornecemos o retorno e abrimos parênteses novamente para o IntelliSense. E temos o primeiro valor anterior, valor atual, índice atual e array. Assim como no mapa de pontos, a redução de pontos executará esse callback para cada elemento de matriz. Isso significa que esse callback será executado cinco vezes para cada elemento. É por isso que sabemos o que será o índice e o array atuais. Assim como no mapa escuro, a matriz será a mesma matriz que usamos para este método.radius. E o índice atual será o índice do elemento iterante atualmente, que será 01234. Não precisamos deles. A única coisa que precisamos é o valor anterior e o valor atual. Mas na maioria das vezes, valor anterior não é frio valor anterior. É chamado de acumulador. O que é acumulador? Vamos conversar em um segundo. Eu só quero mencionar que o método de redução de pontos também espera um segundo argumento ao lado do retorno de chamada. O segundo argumento é o valor inicial e é opcional. Então, vamos colocar 0. Ótimo. Agora, o que é acumulador ou qual é esse valor anterior? O problema é que o método de redução de pontos funciona comprimindo ou acumulando cada elemento da matriz em direção ao resultado final. Isso significa que começamos com algum valor inicial com 0. Certo? Então, quando todos esses callbacks são executados para cada elemento de matriz, ele modifica de alguma forma nosso valor inicial. Tudo bem? E no final, na última execução de callback, temos o resultado. Isso significa que o método de redução de pontos também produz um valor, mas em vez de uma nova matriz, ele produz uma única saída. Então talvez seja 15, não sabemos. Então, como é produzir um valor, vamos colocá-lo, vamos colocá-lo em uma variável. Portanto, o resultado const será hello dot reduce e, no final, vamos apenas o resultado console.log. Ótimo. Agora, se vamos tentar cancelar o acumulador de log e ao lado dele, vamos consolar o valor atual do log. E vamos executar esse script. O que vamos ver, a saída não é bastante óbvia. O que temos? Temos primeiro 0 e depois amplificação indefinida, indefinida, indefinida. Para não nos confundir, na verdade temos cinco registros de console provenientes dos callbacks e o último para o resultado. Deixe-me colocá-lo assim. E nós o executamos. Sim, perfeito. Então, por que temos muitos valores indefinidos? Bem, na primeira execução, quando esse callback for executado para o primeiro elemento 47 acumulador será nosso valor inicial que fornecemos aqui. É por isso que vemos 0 valor atual será elemento atual, que é sete. É por isso que vemos 07. O que quer que retornemos desse callback ficará triste, pois o valor do acumulador para a próxima execução de retorno de chamada. Porque não retornamos nada dessa função. Por padrão, o valor de retorno é indefinido. É por isso que na próxima execução desse callback para o segundo elemento, que é seis, acumulador indefinido. Se vamos retornar um para cada acumulador R1 subsequente será sempre um, e o valor final também será um. Se eu executar o script, você pode vê-lo sozinho. Sempre temos acumulador definido como um, mas isso é muito despejado. Queremos realmente fazer algo com isso. Como podemos usar o ponto reduzido para fazer algo real, podemos realmente usar o método de redução de pontos para encontrar a soma de todos os nossos elementos. Na verdade, podemos digitar acumulador mais valor atual. E é isso. Isso fará o truque. Vamos realmente salvá-lo e vamos ver o que é impresso. Vemos que o resultado é 31. Mas como acabamos com isso, vamos dividi-lo. Para a primeira corrida. Esse callback tem acumulador definido como 0 porque nosso valor inicial é 0, valor atual será sete. Então, temos 0 mais 7. Isso é o que vemos aqui. Então, a partir desse callback retornará sete. Vamos digitar a primeira execução será um retorno sete. Isso significa que na segunda execução desse callback para o elemento seis, acumulador será esse valor de retorno da execução anterior. Portanto, temos acumulador igual a 27 na segunda execução para o segundo elemento, e temos sete mais valor atual. Então temos 7 mais 6, temos 13, o que significa que a partir da segunda corrida, retornamos 13. Na terceira execução desse callback para os elementos nove, acumulador será 13 porque é isso que retornamos do callback para a execução anterior. Quatro elementos, 613, É por isso que agora é 13. Então 13 mais o valor atual será 13 mais 9 será 22. Retornamos 22. Para o quarto elemento acumulador é 2222 mais quatro será 26. Retorno 26. E para o último elemento temos acumulador 26. 26 mais cinco serão 31. E esse será o nosso valor final. Portanto, nosso valor final que temos na variável de resultado será o valor que retornaria da última chamada de volta do método de redução de pontos que é amplo. Esse primeiro argumento é chamado acumulador porque, assim como você observou agora, esse valor é acumulado em todos os retornos de chamada que temos no método de redução de pontos. É uma ferramenta muito flexível e, a princípio, é muito difícil entender como os pontos reduzem funciona, mas confie em mim, é muito flexível. Outro exemplo seria quando temos que produzir um novo objeto a partir dessa matriz. Por exemplo, queríamos ter esse objeto onde a chave seria o índice do elemento e o valor será desvalorizado. Então, por exemplo, o elemento 0 será sete, elemento um será 6, segundo elemento será 934 e depois cinco, certo? Então, suponha que precisamos transformar esse array nesse objeto. Portanto, esse é o nosso resultado desejado. Na verdade, podemos usar pontos reduzidos para conseguir isso. Deixe-me remover esses Comuns e vamos ver como podemos abordar isso. Então, sabemos que precisamos receber um objeto no final. Então, antes de quando calculamos a soma, sabemos que nosso valor final será um número. É por isso que colocamos 0 aqui. Mas agora, como será um objeto, vamos colocar um objeto vazio aqui. Este será nosso ponto de partida. acumulador para a primeira execução será um objeto vazio. valor atual ainda permanece o valor que temos dentro da nossa matriz. Então, agora, para alcançar esse resultado, temos que realmente mesclar valores dentro desse objeto. Como precisamos trabalhar com objetos, precisamos retornar um objeto desse callback porque esse é nosso acumulador. Nosso resultado final novamente é um objeto. É por isso que nosso acumulador é um objeto. Então, vamos retornar e temos que retornar um objeto. Portanto, para mesclar objetos, temos que digitar atribuição de ponto de objeto. Então, o primeiro é o alvo. E aqui vamos fornecer algum valor que será mesclado nesse objeto. Mas antes que possamos mesclá-lo, temos que realmente criar o objeto, certo? Então vamos colocar const, digamos que o elemento atual mapeado. E vamos colocá-lo como um objeto vazio primeiro. E então temos que criar essa única peça de valor que representará nosso elemento atual dentro do resultado final. Então, queremos que esse elemento atual do mapa seja esse objeto. Então, para o primeiro elemento, será 0, 7. Queremos que o elemento atual mapeado seja dessa forma e mesclaremos esse objeto em nosso acumulador. Então, precisamos de alguma forma conseguir que possamos digitar elemento atual mapeado. Então, o índice do nosso elemento, temos que usá-lo. Então, agora podemos realmente colocar nosso argumento aqui e chamá-lo de índice atual. Coloque-o assim. Assim, podemos referenciar que o índice atual do ponto do elemento atual mapeado é igual ao valor atual. E essa linha nos trará essa grade de resultados. Agora nós mesclamos esse resultado em nosso elemento atual mapeado do acumulador, e agora teremos o resultado desejado. Vamos verificar. Arquivo de nó gs. E hoje temos 0 elemento valor 7, primeiro elemento valor seis segundos, 9, terceiro, quarto, 45, grau. Tudo exatamente como eu queria. O que realmente aconteceu aqui? Vamos tentar e acumulador console.log. Bem, e como você pode ver, na verdade, este é um ótimo exemplo dessa saída. Você pode ver como o acumulador está sendo acumulado em todas essas execuções de retorno de chamada. Então, primeiro, para a primeira execução desse callback, mantivemos nosso objeto vazio, certo? É por isso que vemos objeto vazio aqui. Então criamos esse elemento aqui, que é esse, e então o mesclamos em um objeto vazio. Então é isso que retornamos da primeira corrida. Na segunda execução, nós mesclamos isso no primeiro objeto, que resultou nesse objeto com 76, e assim por diante até o último elemento. Então, no final, temos nosso resultado desejado. Muito incrível. redução de pontos é realmente poderosa e muito flexível. É crucial entender isso porque o Dr. US é bastante comum, não tão comum como o método do mapa de pontos, mas ainda assim é usado com muita frequência. Sei que é difícil de entender. Os pontos reduzem completamente quando você o vê pela primeira vez, mas confie em mim, apenas leve algum tempo, experimente com ele, jogue com os diferentes valores. Experimente você mesmo, talvez tente valores de registro no console. Tentei colocar valores diferentes em um raio, tentei retornar valores diferentes daqui. E você verá que depois de algum tempo você entenderá, você terá aquele momento aha. Tenho quase certeza. Acho que este é o método de redução de quatro pontos. Espero que tenha ficado claro. Tentei quebrar o máximo que pude e o resto é sobre você. Vejo você no próximo. 26. Declaração de função VS Expressões: Ei, vamos falar sobre expressão de função e declaração de função. Por que precisamos saber a diferença e quais são essas? Este será mais um vídeo teórico em vez do prático. Mas acho que isso é importante para entender a diferença, mesmo que B possa não ser necessário. Independentemente disso, no final do dia, isso fará de você um desenvolvedor melhor. Vamos. Então, se eu vou voltar ao Arquivo G, S aqui, vou declarar uma função. Vou chamá-lo de Olá, e por dentro cancelarei o log. Meu nome é Andrew. E abaixo eu vou criar um valioso olá para essa variável e para essa variável. Vou atribuir uma função. E por dentro vou imprimir. E você também. Agora, como você pode ver, os dois fazem a mesma coisa. Vamos chamá-los. Então, primeiro vamos chamar olá, e depois vamos chamar olá para o terminal. Vou executar o script e a saída. Bem, é basicamente o mesmo, certo? Então, qual é a diferença? A diferença é que o primeiro exemplo é uma declaração de função e o segundo exemplo é uma expressão de função. O segundo exemplo é, na verdade, uma expressão variável. Então, se eu vou colocar qualquer variável e dar um valor a ela, ela será uma expressão. Então, o mesmo que podemos observar aqui. Basicamente, atribuímos uma função a uma variável. Diferente aqui. Aqui fazemos declaração de função. A diferença mais importante entre esses dois é que, com a declaração de função, não importa onde definimos o tempo da função. Está na parte superior ou na parte inferior, mas com expressão de função e realmente importa. Vamos colocar os dois no final. E vamos chamá-los novamente. Vou executar esse script. E o que eu vejo, a primeira função, que é declaração de função, passou e posso ver a saída. Mas o segundo exemplo, erro de referência com falha não pode acessar o hello tube antes da inicialização. A coisa é que hello two é uma expressão de função e o JavaScript só criará essa função quando, na verdade, o JavaScript for para essa linha, declaração de função será criada ou será içado para a costeleta. Em JavaScript, existe esse conceito de içamento quando as declarações de função são, na verdade, como movidas para o topo antes que o código seja executado. É por isso que não importa onde os definimos. O código sempre, o idioma sempre verá esse código como se declaração da função estivesse no topo, assim. Mas a expressão de função permanece onde foi definida. Assim como nas variáveis, podemos realmente referenciar a variável. Digamos oi, antes de ser criado. Então, se eu vou criar alto abaixo, e se eu tentar executar esse pedaço de código, darei o mesmo adder. erro de referência não pode acessar alto antes da inicialização. Então, como esta é uma expressão e o mesmo que vemos com olá, esta é uma expressão e não podemos acessar essa expressão antes de ser criada aqui no topo. Portanto, a única correção para isso é, bem, acessar olá depois de criarmos essa variável. Então, agora, se eu vou executá-lo, não verei nenhum erro no mundo real em projetos JavaScript molar. Isso na verdade não é uma coisa. Você não observará esse comportamento no código. Bem, porque isso se relaciona principalmente com JavaScript simples e é sempre bom conhecer e entender a diferença, certo? Mas em projetos modernos, como temos ferramentas que processam nosso código, essa coisa não ocorrerá, mas como eu disse, é bom e pessoalmente acho importante entender a diferença. Então, para resumir rapidamente, expressão de função é quando você atribui uma função a uma variável, é mais fácil lembrar se você pode pensar nisso, é que a declaração de função sempre começa com a função como a primeira palavra. E a expressão de função não tem função como primeira palavra porque a primeira palavra que temos const aqui, nós a atribuímos a uma variável e as declarações de função são movidas para o topo, independentemente onde eles são definidos pouco antes do código ser executado. E é isso. Vejo-te no próximo. 27. Funções de arrow e argumentos de função padrão: Ei, neste vídeo, vamos falar sobre funções de seta e argumentos padrão. Vamos. Se eu vou navegar para file.js, vamos criar uma declaração de função simples que chamaremos de meu nome. E imprimirá Andrea, que é meu nome. E vamos criar um segundo exemplo que usa uma função de seta. E a função de seta é uma expressão de função em primeiro lugar, o que significa que ela será atribuída a uma variável. Então vou colocar const, meu nome, 2 é igual a parênteses, depois a função de seta, ou às vezes é chamada de função gorda. E depois desse corpo da função, vou colocar console.log e desenhar dois. Agora, se eu vou chamar meu nome, sabemos qual será o resultado. Mas se eu vou chamar meu nome para, será o mesmo? Vamos verificar. Nó file.js. E vemos que a saída está prevista porque, bem, é apenas uma função, mas agora é uma função de seta. Então, qual é a diferença? A primeira diferença é que as funções de seta têm uma sintaxe mais leve em comparação com as declarações de função. Bem, o problema é que vamos usar muito as funções de seta, especialmente em JavaScript moderno. Eles são ainda mais preferidos do que as declarações de função que começam com a palavra-chave function. Não há porque a sintaxe é mais leve, especialmente quando vamos fornecer callbacks, dois métodos diferentes. É mais fácil fornecer uma função de seta. Então, se eu vou, por exemplo, usar o mapa de pontos da matriz, será mais fácil para mim fornecer uma função de seta. É mais leve escrever uma função de seta em vez de usar a função, depois parênteses. E agora parece que papai, pode até confundir algumas pessoas. Então, eventualmente, não importa qual deles, seja expressão de função ou declaração de função. Não importa porque, no final do dia, nosso código será processado pelas ferramentas de construção que cuidarão de tudo isso sob o capô. A segunda diferença tem algo a ver com essas palavras-chave em JavaScript. Não abordaremos esse caso de uso com a palavra-chave this. Mas eu diria que você realmente deveria ir ao Google e verificar você mesmo. Basta procurar por funções de seta, essas palavras-chave. E a terceira diferença é que as funções de seta nos permitem usar uma sintaxe ainda mais curta do que essa. Quando precisamos retornar um único valor de uma função de seta, podemos omitir usando os colchetes encaracolados para especificar o corpo da função. Então, por exemplo, se meu nome retornar uma string, Andrew, podemos realmente escrevê-la assim, o mesmo que teremos em meu nome. Então deixe-me escrevê-lo. Retorne Andrew, e não haverá diferença, certo? Mas com as funções de seta, podemos até torná-lo mais curto. Então, vou apenas copiar a string Andrew. Vou remover colchetes encaracolados. E eu vou colocar uma string, e agora nada será alterado, mas a sintaxe é muito, muito mais curta. Vamos verificar se meu nome realmente retorna uma string, Andrew, já que ele retorna um valor, vou gravá-lo em outra variável. Vamos chamá-lo de m e depois console.log M. Ótimo. Então eu vou executar o script novamente e você verá angio, correto. Isto é o que retorna do meu nome para ele é muito importante entender que, se você for escrevê-lo assim, a função não retornará nada, que significa que ela retornará indefinida. Deixe-me executar este script e você verá indefinido. Bem, como essa não é uma sintaxe curta, isso é o mesmo que escrever isso, mas sem a palavra-chave return. Portanto, é importante entender que, se você precisar ou se quiser usar sintaxe mais curta, lembre-se sempre de excluir colchetes encaracolados. E também é importante entender que a sintaxe mais curta retorna apenas um único valor. Se você precisar fazer alguma ação dentro de uma função, você não poderá usar a sintaxe curta porque, nesse caso, você não tem onde realmente escrever seu código. Então, neste caso, você é obrigado a fazer alguma operação aqui, certo? Certo, seu código personalizado e, em seguida, no final, você retornaria um valor assim. Portanto, não há diferença se você fizer isso com a palavra-chave return ou se você faz isso com a sintaxe mais curta é o mesmo. É assim você escreve o código sempre que possível, tente usar uma sintaxe mais curta porque bem. É mais curto. Há uma coisa que eu quero mencionar sobre essa sintaxe curta é quando você precisa retornar um objeto. Então, quando temos uma situação, quando precisamos retornar um objeto, por exemplo, nome, entrada. Portanto, esse objeto eu quero retornar dessa função de seta. Bem, com a palavra-chave return, parece assim. Mas como vai parecer sem a palavra-chave return, os objetos também terão colchetes encaracolados e o corpo da função também tem colchetes encaracolados. Se vamos colocá-lo assim. Você verá erro de sintaxe porque bem, isso é errado JavaScript coisas que isso é função, mas não é um objeto. Para realmente corrigir esse problema, você precisa envolver o objeto de retorno entre parênteses assim. Então, dessa forma, ele entenderá que você deseja retornar um único valor que deseja usar uma sintaxe mais curta e está retornando um objeto para verificar se permite executar o script. E vemos que agora temos nosso objeto retornado. Ótimo, tão bem, que se sentam sobre as funções de seta. Vamos utilizá-los muito. Vamos falar sobre argumentos de função padrão. Bem, esse é realmente fácil. Há muitas situações em que precisamos passar argumentos para nossas funções. Por exemplo, meu nome para a única coisa que a função fará. Ele irá registrar o primeiro argumento que vamos fornecer. E vamos chamar esse argumento de meu nome. Então, no lado receptor, temos meu nome e, em seguida, imprimimos meu nome é meu nome. Ótimo. Agora, se eu vou chamar meu nome para, deixe-me remover código desnecessário. Se eu vou executar meu nome para sem fornecer o parâmetro para esse argumento. Bem, neste caso, Meu nome será indefinido porque, bem, nós não o fornecemos, certo? Não fornecemos nenhum valor para o meu nome. Para verificar se podemos ver meu nome está indefinido. E há muitas situações em que temos circunstâncias diferentes em nosso código e variáveis. Eles não produzem valores esperados. Eles não produzem o resultado esperado, certo? Portanto, neste caso, queremos garantir que sempre temos algum valor de fallback para fornecer o valor padrão para esse argumento de função. Precisamos apenas colocar iguais e, em seguida, fornecer um valor padrão. Não sei, John. Tudo bem, agora, sempre que eu não passar nenhum valor para isso, meu argumento de nome, John, ocorrerá e será usado como um fallback. Agora vamos tentar executar o script e você verá que meu nome é John, certo? Porque eu não passo nada. Isso foi apanhado e agora usa John e John são impressos. Se eu vou fornecer angio, John não será usado em vez de Andrew porque Andrew não é indefinido. É um valor que passamos para esse argumento, certo? Ou execute o script. Agora vejo que meu nome é Andrew. Tudo funciona muito bem. Então, se eu vou passar indefinido, o que será impresso? Correto? John? Para verificar se estamos sob script novamente, meu nome é John. Perfeito. Imagine as situações em que temos vários argumentos em uma função. Digamos que meu nome e minha idade, e eu vou imprimir meu nome é e minha idade será minha h. Se eu não fornecer nenhum argumento, Meu nome será indefinido. Meu h será indefinido. Para verificar indefinido, indefinido, perfeito. Agora, posso realmente fornecer um valor padrão para todos eles ou apenas para um argumento. Então, deixe que seja minha idade e, por padrão, será igual a 10. Então, agora, se eu executar novamente, você verá que meu nome permanece indefinido porque não temos nenhum valor de fallback. E minha idade é 10. Talvez. Vamos colocá-lo em John. Vamos derramar Andrew aqui. E vamos colocar indefinido para finalizar nossos pensamentos, vamos dizer direto e nosso conhecimento. Então, para o meu nome e você será pego, e para a minha idade, 10 serão retirados porque fornecemos indefinido. Isso é o mesmo que não fornecer um valor, certo? Se eu vou escrever, meu nome é Andrew e minha idade é Stan. Perfeito. Bem, é isso. Agora você sabe como vamos utilizar as funções de seta. Quais são esses? E agora você sabe sobre argumentos de função padrão. Vejo você no próximo. 28. Interpolação de corda: Oi, Neste vídeo, vamos falar sobre modelos de string ou, na verdade, eles são chamados strings de modelo e interpolação de string. Vamos em file.js. Suponha que eu quisesse imprimir meu nome em uma frase. Quero dizer que meu nome é Andrew, meu h é 10. Para isso, vou criar três variáveis. A primeira variável será nome, que será Andrew. O segundo será h, vai ser 10. E o terceiro será o resultado que vou imprimir no console. Então, para fazer uma frase, terei que concatenar strings porque vou usar valores dinâmicos, que são nome e idade. Na programação. Em outras linguagens de programação, isso geralmente é feito usando o operador plus. Então, isso vai parecer que meu nome é mais nome. Isso produzirá entrada. Então, novamente, mais. E agora o ponto de corda que eu tenho que digitar minha idade é novamente, então mais h. E também temos que cuidar dos espaços. Aqui. Tenho que adicionar um espaço e aqui também. Ótimo. Agora vamos tentar imprimi-lo e executar este script, nó file gs. Meu nome é Andrew May, h é 10 anos. Este é o nosso resultado desejado. Mas, como você pode ver, isso não é muito prático porque, bem, essa sintaxe, na verdade não é conveniente. E se tivermos muitas variáveis e tivermos uma string muito longa, então ela se tornará ilegível. E se houver uma maneira melhor de fazer isso? Bem, na verdade, isso é modelos de string, ou geralmente chamados de strings de modelo. Vamos tentar executar novamente essa linha de código usando o modelo de string. Então, vamos criar outros resultados variáveis para. E vamos usar o modelo de string. Para usar o modelo de string, temos que usar backticks. Então, para strings regulares, usamos aspas regulares, certo? Uma única reclose ou aspas duplas. Para modelos de string, usamos backticks. Então, vou alternar aspas usando a extensão de aspas de alternância que instalei no VS Code. Você pode encontrá-lo no mercado VS Code. Esta extensão alterna aspas, essa. Então eu estou pressionando a ligação de teclas para alternar aspas e eu paro em backticks. Backticks, a string é avaliada como está, como aparece no código. Então vou digitar, meu nome é espaço. E aqui eu queria dinamicamente, digamos injetar um valor. Para fazer isso, temos que interpelar esse valor em uma string. Os modelos de string nos permitem fazê-lo usando a sintaxe de cifrão e colchetes encaracolados. Então, quando colocamos o cifrão seguido de colchetes encaracolados, dentro de colchetes encaracolados, podemos colocar qualquer expressão JavaScript que produza um valor. Esse valor será interpolado nessa string, naquele lugar nessa string. Então, queríamos colocar nomes aqui. Meu nome é nome. Eu coloquei Dodd. Minha idade é de novo, o cifrão seguido de colchetes encaracolados h. Vou salvá-lo. Vou registrá-lo no console ao lado do nosso primeiro resultado. E vamos comparar esses dois. Como você pode ver, eles são os mesmos. Mas a diferença está no resultado da sintaxe para usar modelos de string e o primeiro usa apenas o operador plus e concatenar strings já resultaram. Essa sintaxe é muito melhor e mais abrangente, e essa sintaxe é preferida no JavaScript moderno. Ninguém realmente usa concatenação para concatenar strings, talvez muito raramente, maioria das vezes, você verá interpolação de string usando modelos de string com backticks. Como mencionei anteriormente, a string que aparece dentro dos backticks é avaliada como está. Isso significa que se eu vou colocar muitos espaços vazios aqui, e talvez aqui, todos eles serão incluídos na sequência final. Então, se eu colocar espaços em branco aqui, cadeias de caracteres em branco, elas serão cadeias de caracteres em branco na saída. Vamos vê-lo. Você pode ver que o espaçamento está todo retido. Coloquei três linhas vazias aqui, elas aparecem na saída. Não podemos fazer isso com o operador plus. Se eu vou colocar espaços em branco aqui, terei erro de sintaxe. E se eu tentar executar o script, terei erro de sintaxe, token inválido ou inesperado se quisermos usar linhas vazias em nossa string e quisermos mantê-las, somos obrigados a usar modelos de string. Portanto, isso levará a sintaxe inválida. Vamos colocá-lo de volta como era antes. Tudo bem, Agora entendemos modelos de string, como mencionei anteriormente, dentro de colchetes encaracolados, somos capazes de colocar qualquer expressão JavaScript. E, como lembramos, a expressão é uma entidade que produz um valor. Portanto, temos o nome que é expressão disponível, ele produz a Andrew uma string. O que eu quero dizer é que não estamos limitados a apenas colocar variáveis aqui. Podemos colocar qualquer expressão JavaScript dentro. Por exemplo, vamos usar o operador ternário. Se 10 for maior que cinco, então vamos colocar a variável de nome. Caso contrário, usaremos a idade porque 10 é sempre maior que cinco, sempre teremos nome. Então, vamos tentar ver. E temos Meu nome é Andrew, minha idade é 10. Ótimos trabalhos. Vamos mudar o operador. E agora teremos, meu nome é 10 porque bem, temos falso aqui, e é por isso que recebemos H no final. Então, podemos realmente colocar uma função de cada ano. Vamos criar const e pegar meu nome. E ele retornará John aqui, certo? E dentro de colchetes curly usando interpolação de string, vou chamar essa função. Nessa função me retornará a string. Vamos experimentá-lo. Vamos ver meu nome é John. Minha idade é 10, e é isso. Isso é tudo o que precisamos saber sobre modelos de string ou literais de string e interpolação de string. No final, você precisa se lembrar três coisas sobre modelos de string. Então, o primeiro é que eles usam backticks. Eles não usam aspas regulares. Se você vai colocar citações regulares aqui, isso não funcionará. interpolação de string não funcionará. Se eu verificar, você verá que terei o cifrão e colchetes encaracolados serão impressos. Eu tenho que mudar minhas aspas para backticks, então a interpolação de string funcionará. A segunda coisa a lembrar é que dentro da interpolação de string, podemos colocar qualquer expressão JavaScript. Não somos limitados. E a terceira coisa a lembrar é que a string dentro dos backticks é avaliada como está. Isso significa que, se colocarmos espaços vazios aqui, eles serão incluídos na string. Eles não serão omitidos. É isso. Vejo você no próximo. 29. Destruição de objetos e matriz: Ei, neste vídeo vamos falar sobre objeto e array faz estruturação. Esses dois recursos são muito usados. Vamos verificá-los em file.js. Digamos que eu queria criar um objeto, deixá-lo ser carro. E ele terá as seguintes chaves. Cor, que vai ser vermelha, digamos Gears 5 e talvez tipo de motor. Vamos colocar diesel. Agora digamos que eu queira acessar as chaves desse objeto. Então, geralmente eu faria isso como carro, depois colocando DOD e, em seguida, o nome da chave que eu quero acessar. E se eu quisesse colocá-lo em uma variável, geralmente faria assim. Então, vou declarar uma nova variável chamada engine. E então eu colocaria carro e atenção. E se eu quisesse puxar todos esses objetos, criaria uma variável separada para cada um. Por exemplo, as engrenagens const serão engrenagens de carro e o mesmo que faremos pela cor, certo? Podemos ver isso como três linhas de código separadas. Bem, isso não é muito conveniente no GPS moderno, podemos fazer algo mais simples, destruição de objetos. Então, em vez de fazer isso, deixe-me comentar. Podemos substituí-lo por uma linha. Então vamos colocar const, então vamos colocar colchetes encaracolados para especificar que isso vai ser objeto faz estruturação. Então vamos colocar iguais e o objeto que gostaríamos de destruir, que vai ser carro daquele objeto de carro, queríamos puxar o motor e as engrenagens. Digamos que não precisamos de cor. Então, em colchetes encaracolados, especifico quais chaves eu quero extrair desse objeto. Então, vai ser de cor. E então vou puxar as engrenagens. Essa única linha de código substituirá Esses dois por cores e engrenagens? Se quiséssemos puxar o motor também, nós apenas digitaríamos o motor aqui. E, claro, é muito importante especificar o nome da chave de forma muito estrita. Digamos que se tivermos engrenagens aqui por algum motivo e elas estiverem em maiúsculas, não sabemos disso, certo? E nós destruímos as engrenagens, elas serão indefinidas porque bem, não existe nesse objeto. Talvez vamos tentar e registrar o console, a cor. Assim. Deixe-me rapidamente fazer isso engrenagens e também antigo. Certo. Deixe-me pobre Node arquivo GS e você vê o Colorado e engrenagens diesel de motor indefinido, já que temos engrenagens, objetos a partir de uma letra maiúscula, e nós destruímos engrenagens que não existem nisso objeto. Temos indefinidos, mas outros valores são. Tudo bem. Então, vamos colocá-lo de volta e vamos verificar se ele funciona. Incrível. Agora temos Gears 5, esse objeto está estruturando, pense, é uma ferramenta realmente poderosa. Isso é basicamente tudo o que ele faz. Ele apenas puxa chaves de um objeto. É isso. Isso é basicamente o mesmo que fazer isso com essas três linhas separadas. Eu diria que isso é apenas uma taquigrafia. Ele não traz algo novo. É só uma taquigrafia. Há mais uma coisa nesse objeto apenas estruturando é que, digamos que, com a primeira abordagem com essas três linhas, podemos facilmente renomear variáveis. Se eu quisesse especificar o motor do carro, eu apenas renomearia a variável de motor para motor de carro, assim mesmo. Muito fácil, certo? Mas quando o objeto está estruturando, lembre-se de que sempre temos que especificar chave estrita que gostaríamos de destruir, pois outra forma discutível não existirá. A chave não existirá nesse objeto. Então, como podemos renomeá-los? Bem, para fazer isso, digamos que, em vez do motor, queremos usar o motor do carro. Tenho que colocar dois pontos e , em seguida, o novo nome dessa variável. Então agora, do objeto do carro, eu puxo o motor e renomeei o motor para o motor do carro. O mecanismo não existirá como uma variável. Ele aparecerá como motor de carro. Se eu estiver indo para o mecanismo somente log do console, vamos ver o que teremos. Teremos um erro de referência. O mecanismo não está definido porque essa variável não existe. Puxamos a chave do motor, mas o nome da variável agora é motor do carro. Então, se vamos referenciar o motor do carro, isso não nos dará nenhum erro. Acho que está claro. Então, o mesmo com outras teclas, se você quiser renomear a cor, colocaremos a coluna e, em seguida, a cor do carro. E é isso. Muito fácil, certo? Como uma triste destruição de objetos porque é uma ferramenta realmente poderosa. Vamos usá-lo muito, especialmente no React. Vamos dar uma olhada em um exemplo real que vamos usar no React na verdade. Então, vou criar uma função, digamos que alguma função. E esta função de soma receberá um argumento, vamos chamá-lo de carro de arco. Vamos esperar que nosso carro seja um objeto. E podemos chamar alguma função. E nós forneceremos nosso objeto de carro para o nosso carro, certo? Vamos comentar rapidamente e vamos tentar e console.log, arg, carro assim. E veremos nosso objeto bem simples. Agora, digamos que quiséssemos cancelar chaves separadas de log desse objeto. Então, novamente, a mesma imagem que acabamos de fazer. Então, nós referimos essas chaves usando a sintaxe do nome da chave da porta do carro de arco. Por exemplo, cor de ponto de carro de arco. Certo? Lemos, se eu vou usar o motor, ele vai ser desleal se eu fornecer uma chave não existente, por exemplo, rodas quadradas, certo? Vou ficar indefinido porque bem, essa chave não existe nesse objeto. Em vez de fazer isso, posso usar a reestruturação de objetos e posso usá-lo diretamente dentro do parêntese. Então, a primeira maneira que podemos usar, na verdade essa linha de código, assim. E vai funcionar, certo? Assim como discutimos anteriormente. Mas, em vez disso, eu posso realmente mover esse objeto está estruturando diretamente dentro do parêntese. Então, vou copiar isso e colocá-lo aqui. E agora acabamos de remover ainda mais linha de código. Agora posso acessar diretamente cores e engrenagens críticas. Vamos verificar se lemos e cinco, o que está correto. Bom. Vamos estender esse exemplo um pouco mais. E se eu fornecer um segundo objeto para alguma função? Então, aqui, suponha que eu forneça um segundo objeto. Talvez não seja carro, mas vou colocá-lo como um carro. Tudo bem? E aqui eu espero algum objeto, e espero que esse objeto de soma dois tenha duas chaves, nome e idade. Então, posso referenciá-los fazendo alguns objetos para o nome do ponto ou a idade. Mas, em vez disso, posso novamente usar a destruição de objetos diretamente aqui. Então eu colocaria nome e idade. Usamos a destruição de objetos para os dois argumentos. Então, os argumentos são separados com a vírgula, certo? E as chaves que destruímos são especificadas em colchetes encaracolados com bastante facilidade que alguma função é um bom exemplo porque teremos um pedaço de código muito semelhante no React. Vamos combinar a estruturação do objeto com argumentos padrão. Então, e se eu não fornecer nenhum argumento para alguma função? Deixe-me remover o segundo objeto daqui. E digamos que eu destrua cores e engrenagens. Vamos experimentá-lo. O que vou conseguir? Eu obterei a cor da propriedade não pode destruir de indefinida. O que aconteceu? Bem, o problema é, como você se lembra, quando não fornecemos nenhum argumento para algumas funções, esse argumento que esperamos para um par nessa função será indefinido. Então, o que estamos basicamente fazendo aqui, estamos tentando puxar essas chaves de um valor vazio, que basicamente não existe sob o capô, parece assim. Então, puxamos cores e engrenagens do indefinido. Mas, como você pode ver, essa sintaxe leva a um erro de tipo. Isso está incorreto. Portanto, neste caso, para realmente corrigir esse erro, podemos fornecer um valor de fallback. Então, vou colocar um objeto vazio, e agora vamos ver o que vamos ter. Vamos ter indefinido, indefinido. Bem, isso é esperado porque não fornecemos nenhum valor para esse objeto. valor indefinido retorna para um objeto vazio. E a partir desse objeto vazio, interruptor chaves, cores e engrenagens não existentes. Bem, porque eles não estão definidos em um objeto vazio. Se eu vou colocar a cor verde e tentar registrar o console, você verá que o valor será verde e as engrenagens serão indefinidas, certo? Porque, novamente, nosso valor indefinido retorna para esse objeto. E a partir desse objeto, destruímos a cor nas engrenagens. Há mais uma desvantagem na verdade com essa abordagem. E se eu fornecer um objeto vazio aqui? Como podemos saber, um objeto vazio já é um valor definido, certo? Vou colocar um objeto vazio. Você consegue adivinhar o que vai ser cor e engrenagens? Correto? Vai ser indefinido. Indefinido porque agora a cor e as engrenagens, elas não existem nesse objeto. É por isso que temos indefinido. Indefinido. E se quisermos especificar valores padrão para chaves de objeto separadas? A abordagem é a mesma usando o sinal de igual. Assim, podemos colocar cor por padrão será verde. Vamos colocar um objeto vazio para verificar isso em um segundo. E as engrenagens, por padrão, serão seis, certo? Agora, se eu vou executá-lo, você verá verde e seis. Muito incrível. Então, novamente, para estender esse exemplo, se eu remover o valor padrão para o objeto em si, mas eu mantiver valores padrão para chaves separadas e vou remover um objeto vazio aqui. Vamos tentar executá-lo. Mais uma vez. Não podemos ler cor da propriedade indefinida porque, novamente, temos a mesma situação. Essas duas chaves são tentadas para serem destruídas de indefinidas, o que leva a um erro de tipo. Então, para corrigir isso, temos que fornecer o fallback. Isso é importante. Fornecemos o fallback para o objeto em si, e aqui fornecemos valores padrão para chaves destruídas separadas. Mas posso concordar que essa sintaxe é um pouco confusa. Podemos realmente refatorá-lo para que pareça mais agradável. Eventualmente, acabaremos com mais uma linha de código, mas está tudo bem. Entre parênteses, vou manter apenas o valor padrão para o objeto em si. E em vez de usar a estruturação, vou colocar o nome do argumento. Então, deixe que seja objeto de carro. E em uma nova linha, vou realmente colocar a reestruturação para o objeto, as engrenagens de cores const são iguais ao objeto Car. Agora você pode ver que nós realmente separamos as preocupações entre parênteses. Nós especificamos apenas o valor padrão para o objeto em si e em uma nova linha, quando usamos essa estruturação, especificamos valores padrão para chaves separadas, tão simples quanto isso, eu pessoalmente acho que isso é um dos recursos mais legais disponíveis no GIS moderno. Eu realmente gosto disso, mas também temos um raio estruturando ao lado do objeto. A estruturação, na verdade é muito, muito semelhante. Então, digamos que eu tenha uma matriz ou talvez me deixe realmente remover tudo isso. Vou manter alguma função, mas vou comentar. E abaixo, vou criar algum array. E vou colocar alguns valores como 5, 4, 3, 2 e 8. E da mesma maneira que aplico objetos reestruturados a um objeto, posso usar uma estruturação de raio para significar que usamos a destruição de objetos. Usamos colchetes encaracolados, mas para matrizes, vamos usar colchetes de caixa. Então, da mesma maneira, vamos especificar colchetes de caixa matriz de soma igual. Mas desta vez não precisamos seguir rigorosamente o nome das chaves. Isso se opõe? Temos nomes de chave, mas na matriz não o temos. Na matriz, temos pedidos. Então, quando aplicamos a destruição de objetos, não importa em que ordem você destrói as chaves. Mas em uma raiva é estruturante. É importante. Mas você pode dar nomes que quiser para suas futuras variáveis. Por exemplo, eu gostaria de interromper seu, o segundo elemento dessa matriz. Então, para fazer isso, sou obrigado a primeiro destruir o primeiro elemento, a ordem que você especificar em uma estruturação de raio será a mesma os elementos vão na matriz original para destructor o primeiro elemento, eu forneço o primeiro elemento. E agora eu destruí O segundo elemento, segundo elemento, que será 4. Então, o primeiro elemento será 5, o segundo elemento será quatro. Como você pode ver, o pedido é retido. Primeiro elemento cinco segundos 4. Se eu vou colocar o terceiro elemento aqui, você pode adivinhar o valor? Bem, sim, vai ser três. Vamos verificar isso. Registro do console, primeiro elemento, segundo elemento e terceiro elemento. Note o arquivo GS, o que vemos 5, 4, 3, exatamente os mesmos valores. Se eu, por algum motivo, quisesse emitir esse elemento, digamos que eu o use assim, certo? Const, segundo elemento. Bem, isso não vai funcionar. O segundo elemento agora será o primeiro elemento, que é cinco. Se eu consolar o log, você o verá, será cinco. Porque, novamente, a ordem é importante quando você aplica uma reestruturação porque os elementos, eles são ordenados, eles não têm nomes de chave. Você pode dar qualquer nome a essa variável, mas você precisa manter a ordem. Eu acho que finalmente está bem claro, eu diria que uma estruturação de raio é usada da mesma maneira que a reestruturação de objetos. Se você quiser fazer algo semelhante com uma estruturação de raio entre parênteses quando estiver usando a função, ela funcionará. A diferença é apenas que, com a destruição de objetos, q são necessários para usar colchetes encaracolados com a estruturação do raio, você usará colchetes de caixa e também a ordem. Lembre-se de que, em uma matriz, os elementos são ordenados e é por isso que você precisa destruir todos os elementos anteriores. Se você quisesse destruir o número do elemento. E se eu quiser destruir o quarto elemento, sou obrigado a interromper seus três primeiros. Isso é inevitável enquanto em chaves de objetos, elas não são ordenadas. É por isso que você pode usar qualquer pedido. Quando destruir as chaves, é sobre objeto e uma estruturação de raio. Vamos usá-lo muito e espero que tenha ficado claro para você. Vejo você no próximo. 30. Espalha e desocupação: Oi, Desta vez vamos falar sobre o resto e espalhar os operadores. Esses dois são fortemente acoplados ao objeto em raça e são muito usados em js modernos. Vamos descobrir o que eles fazem. Se eu voltar ao File GAS, deixe-me talvez criar uma função e o topo que eu vou nomear alguma função. Ele vai receber o argumento número um, argumento número 2 e 4. Agora console religioso log arg1, arg2, perfeito. Abaixo, deixe-me chamar essa função e deixe-me fornecer olá como o primeiro argumento. O segundo argumento será n para o terceiro será 15 em diante, talvez apenas uma função de seta vazia, e então deixe ser apenas o número 5. Ótimo. Se vou executar esse script, verei que tenho Hello Andrea, dois primeiros argumentos. Agora, como podemos realmente alcançar o resto dos argumentos e como podemos acumulá-los em uma única unidade, em S e Google suportável, é por isso que o operador restante existe. Ele acumula o resto, os argumentos sobre o resto de algo em um único barril. Então, no topo, vou colocar uma referência rápida para nós. Portanto, o operador rest acumula ou digamos valores falsos em uma única variável. Falhas. Ótimo. Então, para usar o operador restante, temos que colocar os três pontos e o nome da variável na qual o resto será escrito. Então, deixe que seja erast de arcos. Pode ser qualquer nome. Agora deixe-me tentar e console log o resto dos arcos. E agora temos 15 funções anônimas e 5, basicamente vamos o resto dos argumentos que não definimos. Então podemos ver nossos dois primeiros argumentos são olá e ONG, e o resto é 15, a função e cinco, ótimo, se eu vou remover o R2 aqui, você pode adivinhar como o resto do RX vai mudar? Vamos experimentá-lo, certo? Então, agora temos Andrew no início do que 15 funções e cinco. E é assim que o operador restante funciona. Ele só pega o resto dos valores e os dobra em uma única variável, assim. Agora, vamos ver como podemos usar o operador restante dentro de objetos e matrizes. Deixe-me comentar isso. E eu vou criar um objeto, diria que vai ser pessoa e o nome será Andrew. Talvez a idade seja 10. E suponha que eu tenha objeto está estruturando aqui. E eu gostaria de pegar talvez o nome daquele objeto pessoa que vou cancelar a bagagem. Podemos receber nota angio. Talvez vamos adicionar mais chaves lá. Digamos que jogos de hobby, perfeitos. Agora, e se eu quiser de alguma forma recuperar apenas a chave de nome e o resto das chaves, eu gostaria de dobrar em um novo objeto completamente novo. Nesse caso, novamente, posso usar o operador restante. Assim como na função, vou usar três pontos dentro do objeto que faz a estruturação e o nome do objeto no qual o resto será escrito. Então, deixe que seja o resto da pessoa. Agora deixe-me tentar registrar o console o resto da pessoa. E o que vou conseguir, vou conseguir um novo objeto com o resto das chaves que não destruí. Então eu destruí apenas o nome. E o resto é h e hobby. É por isso que no novo objeto, que é o resto da pessoa, vou ver H e hobby se vou adicionar H aqui. Agora, o resto da pessoa conterá apenas hobby porque este é o resto. O que resta? Vamos verificar isso. Jogos de hobby perfeitos. Se eu vou destruir o hobby também, você pode adivinhar o valor agora? Certo? Vai ser um objeto vazio. Se eu vou remover todas as chaves, você pode adivinhar o valor agora? Correto. Vai ser exatamente o mesmo objeto porque o resto, bem, são todas as chaves que não destruímos desde que não ouvimos nada. O resto é basicamente tudo aqui. A mesma regra se aplica ao apagar. Deixe-me comentar isso. E na parte inferior, vou criar alguma matriz. E vou colocar 5, 4, 3, 10 e 8, certo? E vou aplicar uma reestruturação de ataque. Então const pântanos colchetes de alguma matriz, de alguns re, eu gostaria de pegar primeiro elemento e o resto. Gostaria de escrever em uma variável completamente nova. Então, novamente, vou colocar três pontos e o nome da variável, que será o resto de alguma matriz. Vamos verificar se vou consolar registrar o resto de alguns raios. E eu vou pegar 4, 3, 10 e 8, que é o resto da matriz que eu não destruí. Se eu vou destruir seu segundo elemento. Agora, o resto vai ser 3, 10 e oito porque bem, eu tenho dois primeiros elementos e o resto é 310 e 8. Se eu verificar isso correto, tudo funciona perfeito. Agora, não falamos sobre o operador spread, mas podemos ver que ele também tem os três pontos. Bem, o problema é que os operadores de resto e spread, eles têm a mesma sintaxe, mas eles são usados em contextos diferentes e é muito fácil perdê-los confusos. Como sabemos, o operador restante acumula ou falsa o resto de algo em uma única variável. Eles espalham o operador faz exatamente o oposto. Ele desdobra algum valor. Então deixe-me demonstrar isso para você. Então, suponha que tenhamos um objeto. Tudo bem, onde está? Vamos, vamos reutilizar esse objeto de pessoa. E digamos que eu tenha outro objeto que é chamado de outro objeto. E tem alguns campos, como o genoma da IA, e o nome deles será Alex, e talvez o carro seja BMW. Ótimo. Agora, e se eu quiser mesclar esses dois objetos? Podemos usar o operador spread para conseguir isso. Então, abaixo, vamos criar um objeto completamente novo, que chamaremos de objeto mesclado. Vai ser um objeto vazio. E nesse objeto vazio, vamos primeiro espalhar o objeto da pessoa e depois vamos espalhar algum outro objeto. Então, primeiro espalhamos a pessoa e depois espalhamos algum outro objeto. Você pode adivinhar o que vai ser o vale do objeto Merced. Vamos verificar o objeto em marcha. E vemos que o novo objeto tem todas as chaves que temos pessoalmente e em algum outro objeto combinadas. Bem, como eu te disse antes, o operador spread desdobra valores. Então, neste caso, ele desdobrou primeiro o objeto da pessoa e, em seguida, desdobrou algum outro objeto. Além disso, como você já pode notar, ele tem exatamente a mesma sintaxe, três pontos que o operador restante, mas eles têm a diferença subjacente que, novamente, o operador spread desdobra valores enquanto o operador restante os dobra. Vamos dar uma olhada em outro exemplo com objetos. E se, em vez disso, eu só vou mesclar diretamente algum outro objeto dentro da pessoa. Eu posso facilmente fazer isso assim. Algum outro objeto. E é claro que tenho que colocá-lo no topo. E agora não preciso de objeto mesclado. E agora nosso novo objeto pessoa conterá todas as chaves da própria tigela e de algum outro objeto. Isso é muito flexível porque agora você pode usar o operador spread para gerenciar objetos como quiser. Você pode mesclar objetos juntos. Você pode mesclar um objeto em outro. E há alguns outros casos de uso que permitem que você use esse spread de alguma forma para desdobrar as chaves de um objeto em outro lugar. No nosso caso, o que acabamos de fazer, desdobramos todas as chaves desse objeto no objeto Person. Se eu vou remover o operador spread, vamos ver o que será desvalorizado. Teremos algum outro objeto como uma pessoa de insight chave. E essa chave manterá o valor do objeto com chaves, outro nome e carro. Por que temos isso assim? Bem, essa sintaxe que você vê aqui é basicamente a abreviação de algum outro objeto, dois pontos, algum outro objeto. Essa é a chave, esse é o valor. Mas quando temos uma situação, quando a chave terá o mesmo nome que a variável que mantém o desvalor, que é algum outro objeto. Podemos usar a taquigrafia e isso funcionará. Perfeito. Agora vamos ver o operador de propagação no apagamento. Vou comentar isso. E eu vou incomum ao nosso conjunto de somas. Então, aqui temos o resto de algum array. Na verdade, vamos remover isso. E vamos usar esse exemplo. Y é, vamos criar uma nova variável e nenhuma matriz, e deixá-la ser 123. Bom. Agora, da mesma forma que acabamos de mesclar objetos e exatamente da mesma maneira que somos capazes de mesclar apagar, certo? Então aqui vou criar uma matriz completamente nova. Vou chamá-lo de resultado. E nesse novo array, primeiro vou desdobrar o resumo, e depois vou desdobrar outro array. Então, no final, vamos concatenar os dois arrays. Resumo e não se esqueça de três pontos. E depois outra matriz com três pontos. Agora somos apenas resultados de log do console e eventualmente, receberemos dois arrays combinados. Incrível. Isso é espacialmente flexível com matrizes porque somos capazes desdobrar algum array em outro array em qualquer lugar. Significa que se eu vou apenas substituí-los, vou trocá-los, certo? Terei pedidos completamente diferentes porque agora outro array vai primeiro. É por isso que vejo 123 e o array resultante. Se eu for remover o operador spread de ambos. Agora, nossa matriz tem apenas dois elementos em que cada elemento é uma matriz em si. Certo? Então, temos uma matriz de dois elementos. primeiro elemento é uma matriz, segundo é uma matriz, mas isso não é exatamente o que queremos. Normalmente, não queremos esses arrays aninhados. Queríamos trabalhar com corrida mais plana porque isso é conveniente e bem, isso é normal de se ver. Haverá muitas situações em que teremos que usar o operador spread em matrizes. E gostaríamos de seguir rigorosamente alguns pedidos com o operador spread, somos capazes de colocar quaisquer valores em qualquer lugar que quisermos. Assim como estou fazendo agora, certo? Então você pode adivinhar o valor, o valor resultante, se eu colocar essa linha de código, Deixe-me ver. Então, primeiro, terei outro array. Depois de todos os valores de outra matriz que é 1, 2 , 3, vou ter 15, 16 e 12. Depois disso, terei todos os valores do resumo. E no final terei 16, 1 e 0. Muito legal. Eu acho que isso é tudo sobre os operadores de spread e rest. Vamos usá-los muito. Eles são muito, muito úteis. Então eu aconselho você a se sentir confortável com isso e praticar um pouco. Eles podem ser confusos, mas acabam sendo muito fáceis. Então confie em mim, leve algum tempo, acostume-se com isso e eu vou te ver no próximo. 31. Código sincronismo, Callstack e Loop de eventos: Olá, finalmente chegamos ao nosso tópico final em JavaScript, uma promessas de código de coletor e coletor e esperam assíncrono. Este é o tópico mais importante no GS moderno, o conhecimento desse tópico é essencial. Sem esse conhecimento, o desenvolvimento de JavaScript nunca se sentirá completo para você. É por isso que sugiro ficar o mais confortável possível com esse tópico. Para entender um código de coletor e coletor e promessas, você deve entender tópicos mais profundos, como o GPS funciona sob o capô, o que é loop de eventos e pilha de chamadas? Neste vídeo, vou tentar explicar em termos simples como o JavaScript funciona para entender o conceito de promessas, soltar. O que você vê na tela agora é uma visão geral de alto nível de como o JavaScript executa o código. Esta imagem descreve como o GS é executado dentro do navegador. Para o NodeJS, será um pouco diferente, mas é bom usá-lo para nosso caso de uso. Então, no quadro amarelo, você pode ver partes do mecanismo JavaScript que são chamadas de pilha e pilha de chamadas. A pilha está no espaço alocado na memória onde todas as variáveis definidas vivem durante a execução do código. A pilha de chamadas é aquele local de throughput que o JavaScript decide o que executar. Em seguida, falaremos sobre pilha de chamadas e um momento. Fora do quadro GS, você pode ver APIs da Web, retorno de chamada, fila e loop de eventos. Tudo isso não faz parte do mecanismo JavaScript. Isso significa que eles são definidos pelo ambiente em que o JavaScript é executado. Conhecemos dois ambientes de execução JavaScript primários, navegador e NodeJS. Por exemplo, as APIs da Web incluem coisas como API DOM ou Fetch API, que fazem parte do ambiente do navegador. Somente, as APIs da Web não são implementadas em Node.JS. Não temos recursos de manipulação de HTML como documento get element by ID e NodeJS. Esses são recursos implementados no ambiente do navegador só sabem gs, no entanto, implementa algumas coisas das APIs da Web. Por exemplo, defina um tempo limite. Eles parecem exatamente os mesmos em ambos os ambientes, mas sob o capô, a implementação é diferente. Você já deve ter ouvido falar que o JavaScript é uma linguagem de encadeamento único. Mas o que isso significa? Isso significa que o JavaScript tem uma única pilha de chamadas. Como pilha de chamadas únicas significa que o idioma pode processar apenas uma operação por vez. Imagine uma porta simples. Poucas pessoas ao redor tentando passar pela porta podem caber apenas uma pessoa de cada vez. Não pode caber às pessoas ao mesmo tempo em que a primeira pessoa entra na porta. E se essa pessoa ficar mais alta do que outras pessoas que tentam passar pela porta terá que esperar porque não conseguem entrar somente depois que a pessoa do estoque sair da porta, outras pessoas poderão continuar e passar pelo mesmo com o mecanismo JavaScript se houver duas linhas de código indo uma após a outra, por exemplo, dois logs de console, sabemos que a primeira linha de código sempre será executada primeiro e somente após os acabamentos de primeira linha, segunda linha será executada. Isso significa que, se a primeira linha de código levar cinco anos para ser executada, a segunda linha de código aguardará todos esses cinco anos para que a primeira operação seja concluída, e somente depois disso será executada. Então, novamente, o JavaScript é uma única linguagem encadeada com a pilha de chamadas únicas. Devido a uma única pilha de chamadas, mecanismo GS pode processar apenas uma operação por vez. A pilha de chamadas é um armazenamento temporário para todas as funções pendentes a serem executadas. E é organizado como uma pilha, uma estrutura que segue o último método de primeiro a sair. Por último, primeiro a sair significa que último elemento adicionado ao o último elemento adicionado ao armazenamento sempre será removido primeiro, uma pilha de placas é um exemplo perfeito de último a entrar, primeiro a sair, imaginar uma pilha de placas. Você empilha placas umas sobre as outras. Depois de ter modelos uns sobre os outros, digamos que você precise remover a primeira placa da parte inferior. Você não pode simplesmente tirá-lo de baixo direito? Se você fizer isso, a pilha cairá e as placas se espalharão. A única maneira de você tirar isso jogado é remover todas as placas do topo, uma a uma até chegar à placa desejada na parte inferior, esse tipo de organização é chamado de pilha. A última placa adicionada à pilha sairá da pilha primeiro. Assim, o nome é o primeiro a sair. O Java poderia chamar stack segue exatamente a mesma organização. Agora imagine um contêiner. Esse contêiner será a pilha de chamadas. À esquerda, há um simples pedaço de código. Vamos ver como o JavaScript protestaria contra esse snippet. Javascript divide o código em funções. Quando o JavaScript precisa executar uma função, a função é adicionada ao topo da pilha de chamadas. Toda vez que a função sai ou retorna, ela é removida da pilha de chamadas. Então, primeiro, o JavaScript vê console.log. Você está pronto? Ele é adicionado à pilha de chamadas do que executado e imediatamente removido. Depois disso gs, Cs, imprima minha biografia, ela é adicionada à pilha de chamadas dentro de imprimir minha biografia, GS primeiro vê, obtenha primeiro meu nome, que significa que foi adicionado ao topo da pilha de chamadas. Gs olha para dentro, Get FirstName e vê que esta função retorna um valor. Uma vez que a função retorna, GS, a remove da pilha de chamadas. A execução da impressão minha biografia continua. Agora gs, Cs função GetAge, a mesma situação. Gs olha dentro do GetAge, a função retorna e é removida da pilha de chamadas. Depois, há console.log final. Meu nome é Andrew, minha idade é 10, adicionada e removida instantaneamente. Imprima minhas saídas biográficas e a pilha de chamadas está vazia. Agora, a execução do código principal ou do mainframe está concluída. A notória pilha máxima de chamadas excedida ou erros de estouro de pilha ocorrem quando o tamanho da pilha de chamadas é inflado e o número ficou ridiculamente enorme que o mecanismo não pode processar esse número de operações dentro do pilha de chamadas. Porque o JavaScript tem uma única pilha de chamadas que é organizada de uma maneira que você acabou de ver. É chamado de bloqueio. Lembre-se, uma operação de cada vez, próxima função não será executada até o término anterior. Isso nos leva ao termo síncrono, que basicamente significa que a execução vai uma a uma como a vemos no código. O comportamento de bloqueio pode ser facilmente absorvido dentro do ambiente do navegador. Em qualquer página, clique com o botão direito do mouse, selecione, Inspecionar e, em seguida, abra a guia do console. Dentro da guia do console, podemos executar qualquer JavaScript válido dentro do navegador. Por exemplo, console.log. Uau produzirá wow impresso no console. Perfeito. Mas e o comportamento de bloqueio dentro do ambiente do navegador, temos a função de alerta e é um bom exemplo para demonstrar o comportamento de bloqueio. Então, vou digitar Alert alto. E quando eu pressiono Enter, o que acontece é que primeiro eu vejo o pop-up que diz alto, mas o que acontece sob o capô? Sob o capô, a função de alerta foi adicionada à pilha de chamadas e ainda não foi removida porque o alerta não saiu e o alerta não retornou nenhum valor, o que significa que o alerta ainda é dentro da pilha de chamadas e bloqueia a execução de todas as chamadas de função subsequentes. Vou registrar qualquer coisa no console. Quando pressiono Enter. Nada acontece porque atualmente, neste momento, alerta está dentro da pilha de chamadas e bloqueia a execução, e continuará bloqueando a execução até que a função de alerta retorne ou saia. E isso vai acontecer o que eu vou pressionar, Ok, então vou pressionar console.log. Vou executar o log do console mais duas vezes e depois vou pressionar OK, vamos ver o que vai acontecer. Agora. Você vê como tudo acabou de descongelar sob o capô. A função de alerta foi removida da pilha de chamadas e a execução continuou. É por isso que posso ver todos os meus logs do console S3 para os quais pressionei Enter anteriormente. Ótimo. Agora entendemos o código de sincronização. Como você pode ver, não é muito conveniente esperar sempre a conclusão de uma operação. É aqui que um código de sincronização vem para o resgate. Quando o JavaScript lê um pedaço de código coletor, ele é processado, não executado, processado em segundo plano e, uma vez processado, ele é colocado em uma fila separada para espera, que aguarda a pilha de chamadas ficar vazio quando todo o código de sincronização é executado e a pilha de chamadas fica vazia, o código assíncrono, que foi colocado na fila de espera, é empurrado para a pilha de chamadas e agora está sendo executado. Existem recursos de linguagem especiais que nos permitem escrever código assíncrono. São promessas e retornos de chamada, cujas implementações são expostas a nós pelo meio ambiente. Navegadores, APIs da Web processam o código em segundo plano e atrasam seu loop de eventos de execução neste sistema é algum tipo de observador para a pilha de chamadas e a fila assíncrona que aguarda, uma vez chamada pilha está vazia. loop de eventos extrai itens da fila de espera e os coloca na pilha de chamadas. Esse conceito introduz um modelo de execução de código sem bloqueio. Isso não altera o fato de que a pilha de chamadas pode processar apenas uma operação por vez, mas permite executar o código de maneira sem bloqueio. Vamos considerar um caso com duas operações. Envie uma solicitação para um servidor e imprima hello no console. A solicitação levaria 500 milissegundos para ser concluída durante a impressão Hello levaria apenas dez milissegundos se for com o log do console modal de sincronização teria que esperar 500 milissegundos para a solicitação que você terminar e só então olá é impresso. Com o modelo sem bloqueio, a solicitação seria processada forma assíncrona em segundo plano. Bem, o código de sincronização continua sua execução. Nós veríamos Hello ser impresso imediatamente após dez milissegundos e a solicitação em segundo plano, terminaremos sua execução em algum momento no futuro após 500 milissegundos sob o capô, há na verdade, várias filas de espera. Um para temporizadores, um para sacos frios, 14 promessas, etc. Eles têm prioridades diferentes e certas ordens. Por exemplo, as promessas têm prioridade sobre retornos de chamada para não complicar demais isso, vamos imaginar que haja uma única fila para todo o código assíncrono. Um dos exemplos de código assíncrono são retornos de chamada. Callback é uma função que é passada como argumento para outra função. retornos de chamada não são assíncronos por padrão, mas aqueles expostos pelas APIs da Web são realmente. Por exemplo, vamos dar uma olhada no setTimeout. Ele está disponível em ambientes conhecidos gs e navegadores. Vamos dar uma olhada em dois exemplos. Um dentro do GS e outro dentro do navegador. Na verdade, não importa onde vamos usar o SetTimeout. Mas quanto mais melhor, não é? O primeiro exemplo estará dentro de nenhum GS. E já preparei esse código simples com dois logs de console e setTimeout. Portanto, setTimeout espera que forneçamos dois argumentos, onde o primeiro argumento é o retorno de chamada que será executado após o número de milissegundos que fornecemos. Como segundo argumento, neste caso, eu forneço a 0 milissegundos, isso significa que a execução não será atrasada. Mas vamos ver como o código será executado. Você consegue adivinhar o resultado? O que virá primeiro? Vamos ver. Vou executar o script e veremos 1, 2, e só então o tempo limite é acionado. O problema é que setTimeout é assíncrono. Isso significa que o tempo limite, o retorno de chamada foi adicionado à fila de retorno de chamada em segundo plano. Vou fornecer 2504,52 segundos. Vamos ver como a imagem será diferente. Eu executo o script, vejo 12. Então eu vejo o atraso de 2,5 segundos. E só então o tempo limite do IC dispara sob o capô. Settimeout foi processado pelo código. Settimeout foi adicionado à pilha de chamadas, mas o retorno de chamada e a execução do timer foram delegados às APIs Node.js a serem processadas em segundo plano, setTimeout foi removido da pilha de chamadas. Isso significa que a execução continua. Em seguida, vemos o registro do console um na pilha de chamadas e removido instantaneamente. E o mesmo com o segundo log do console adicionado à pilha de chamadas e removido instantaneamente. E uma vez em segundo plano, o temporizador é processado após 2,5 segundos no futuro. Esses callback serão adicionados da fila de retorno de chamada em segundo plano para a pilha de chamadas e, em seguida, executá-lo. E não importa quantos milissegundos vou fornecer para o segundo argumento. Ele será sempre protesto de forma sem bloqueio, e será empurrado para a fila de retorno de chamada. E somente depois que a pilha de chamadas ficar vazia, o loop de eventos puxará esse callback da fila de retorno de chamada em segundo plano e o enviará para a pilha de chamadas. Não importa quantos milissegundos eu forneça ou onde eu coloquei esse código, ele sempre protestará de forma assíncrona. Se eu colocá-lo no meio e eu fornecer 0 milissegundos, a imagem é a mesma. Vamos dar uma olhada no segundo exemplo. Você pode ver um HTML de índice muito básico, que tem um único elemento de botão com id, btn. Então, dentro do script, acabei de puxar esse botão usando a API DOM, seletor de créditos documentados, hashtag, meu btn. Em seguida, para esse elemento de botão, anexo um ouvinte para o evento onClick e para o evento onClick na função BET e clique será acionado. Agora ele está vazio, mas vamos adicionar algo dentro do log do console hello. E deixe-me realmente abrir esse index.HTML dentro do navegador. Clique com o botão direito do mouse em revelar Clique duas vezes nele e boom, aqui vamos nós. Clique com o botão direito do mouse E abro a guia do console, pressiono clique em mim e vejo olá é impresso assim como definimos dentro do manipulador para o evento onClick. Perfeito, vamos realmente copiar e colar o código que não tínhamos em GS para o manipulador. Agora, o comportamento será o mesmo que dentro do não, GS. Vamos verificar isso. Volto ao navegador, atualizo a página. Pressiono o botão e, como posso ver, primeiro vai 1, 2, e só então o tempo limite é acionado, mesmo que seja colocado entre os logs do console. Se eu colocá-lo no trabalho e se eu vou colocar, digamos dois segundos. Eu atualizo a página. Eu clico na parte inferior, um a dois segundos se passaram em disparos de tempo limite do IC. Bem, a imagem é a mesma. Então, o que acontece é que, uma vez que o JavaScript lê setTimeout, setTimeout está sendo adicionado novamente à pilha de chamadas, mas o retorno de chamada e o timer onde delegaram desta vez para as APIs da Web dentro do navegador. Isso significa que eles estão sendo processados em segundo plano. A execução continua. Settimeout é removido da pilha de chamadas. Registro do console adicionado à pilha de chamadas, executado e removido. E o mesmo com o segundo registro do console. Quando o código for concluído, o mainframe ou o código principal for concluído, loop de eventos verificará constantemente a fila de retorno de chamada. Então, o di callback é adicionado à fila de retorno de chamada. E, em seguida, o loop de eventos vê isso e empurra esse callback para a pilha de chamadas. E depois disso, a chamada sai pela culatra. Mas vamos ver isso com o exemplo de bloqueio. E se eu for colocar alerta em vez de log do console, vou digitar alerta alto. E vou remover o segundo log do console. E agora a pergunta é definirá o tempo limite para ser processado em segundo plano assim que o alerta começar a bloquear o loop de eventos, vamos ver. Eu atualizo a página. Pressiono o botão, alerto disparos e agora ele bloqueia o loop de eventos. Mas não vejo nada dentro do console. E se eu for pressionar o botão OK, somente depois disso, o código começará a processar o retorno de chamada. Porque setTimeout aparece após a linha de alerta. Se vamos colocar setTimeout antes da linha de alerta, a imagem será diferente. Para atualizar a página. Clique no botão Me novamente. Alert começa a bloquear o loop de eventos, mas agora SetTimeout já delegou o processamento desse callback para APIs da Web. Isso significa que, enquanto o alerta bloqueia o loop de eventos, callback está sendo processado por APIs da Web em segundo plano. E agora esse retorno de chamada está dentro da fila de retorno de chamada aguardando para ser empurrado para a pilha de chamadas. Se eu vou pressionar Ok, verei instantaneamente disparos de tempo limite. Certo? Mas se eu vou pressionar Ok, dentro desses dois segundos aqui, a imagem mudará, atualizará a página, clique em mim, pressione instantaneamente Ok. E você pode ver que foi ainda menos de dois segundos porque, uma vez que eu clico no botão, isso é instantaneamente delegado às APIs da Web. E não importa por quanto tempo a linha de alerta bloqueará a execução. Isso já está processado em segundo plano. Ótimo. Então, em termos simples, podemos dizer que o código assíncrono é esse tipo de código que sempre é executado depois de todo o código síncrono. Para lembrar facilmente esse conceito, imagine duas colunas, uma para sincronização e 14 código assíncrono, digamos que gs comece a ler o código e depois classifica o código em zinco e as colunas de zinco. E quando chegar a hora de executar o código, basta colocar a coluna assíncrona abaixo da coluna do coletor. E aqui vai você. Esta é a ordem na qual o código será executado. Claro, isso é simplificado demais, mas dá a ideia básica. No GAS moderno, você verá promessas em todos os lugares. A base para promessas é o código assíncrono. É por isso que é tão importante alavancar esse conceito. Solicitações de servidor, operações de banco de dados, operações de leitura de arquivos Por tudo isso, usaríamos promessas e código assíncrono. Espero que tenha sido claro e agora você tenha entendido melhor como o GS interpreta o código. Da próxima vez, vamos falar sobre promessas e async aguardam. Veja outro. 32. Código de sincronização e sincronismo - - e Async Sync: Oi, Neste vídeo, finalmente vamos falar sobre promessas e async aguardam. Vamos. Sabemos que a base para promessas é código assíncrono. Mas então o que é uma promessa? Uma promessa é um objeto e isso produzirá algum valor em algum momento no futuro. De forma sem bloqueio assíncrona, uma promessa pode ser um dos três estados pendentes estado, estado resultados e estado rejeitado. Embora uma promessa esteja no estado pendente, isso significa que a promessa não resolveu ou ainda não produziu nenhum valor, uma promessa é resolvida. Isso significa que a promessa já produziu um valor. E quando as promessas rejeitadas, isso significa que essa promessa foi lançada e somada e não produziu nenhum valor. Tudo bem, vamos ver como é uma promessa muito básica, e vamos ver como podemos começar a trabalhar com eles. Então, deixe-me criar uma variável. Vou chamá-lo de fazer alguns. E dentro dessa variável vou chamar de construtor prometido. Para fazer isso, tenho que fazer uma nova promessa. E o construtor de promessa, tenho que fornecer o executor ou o retorno de chamada que inicializará a promessa. Então, vou passar um retorno de chamada vazio. E esse retorno de chamada que passo para o construtor sempre recebe dois argumentos. O primeiro argumento é algo chamado resolve. O segundo é rejeitar. Portanto, o primeiro argumento é a função que devemos chamar dentro do callback para produzir um valor dessa promessa. E quando chamamos de rejeição, obviamente lançamos um erro dessa promessa. Nós rejeitamos essa promessa. Então, por exemplo, vou chamar resolve. E como você pode ver pela inteligência, tenho valor que tenho que passar. Resolvemos uma promessa com algum valor porque a promessa produz um valor. Então, por exemplo, olá. Agora, vamos tentar usar essa promessa de alguma forma. Então lembre-se de que uma promessa, não é uma função. Então, seria errado chamá-lo com parênteses como se isso fosse valioso fosse uma função. Basta fazer referência à promessa para que ela funcione. Se eu salvar o arquivo e então eu executar o script, você verá que nada vai acontecer porque bem, não imprimimos nada na saída. Mas se eu estiver indo para o log do console, faça alguns, neste caso, verei que o objeto promessa será impresso. É importante notar que o que você vê aqui é o objeto promessa. Portanto, é a promessa em si. Não é o valor que a promessa resolve. retorno de chamada que passamos para o construtor de promessa é inicializado de forma síncrona. Isso significa que sempre que nos referimos a alguns, esse retorno de chamada será executado de forma bloqueada. No entanto, o valor que será resolvido a partir dessa promessa é resolvido de forma sem bloqueio. E para resolver um valor dessa promessa de obter a string real hello, tenho que usar essa sintaxe de promessa especial chamada então ou apenas sintaxe venerável. É chamado às vezes assim. Então faça um pouco de DOD. E a partir da inteligência você pode ver que eu tenho três opções pegar finalmente, e então, para resolver um valor dessa promessa, eu tenho que chamar o método ponto, então, no objeto de promessa e o método ponto-ponto 2D, Tenho que passar um retorno de chamada. E esse callback como primeiro argumento, receberá o valor do resultado dessa promessa, por exemplo, valor resolvido. E se eu tentar e consolar o valor do resultado do log, você verá que será nossa string Olá. Se eu executar o script, você verá que o Hello é impresso na saída, o que está correto. Agora, e a função de rejeição que recebemos como segundo argumento no inicializador. Então, vamos tentar e, em vez de Resolver, usar reject e, uma vez que eles o chamem, você pode ver um motivo de argumento opcional. Então, sempre que rejeitamos uma promessa, rejeitamos por algum motivo, na maioria das vezes, você rejeitará uma promessa com um erro e outras promessas que você vai deixar dizer encontrar na natureza, todos eles rejeitarão com um objeto de somador. É por isso que, em vez de apenas passar a rejeição com essa promessa falhou. Mas a mensagem assim, em vez disso, passamos por um novo editor e a mensagem será promessa, falha na nota. Agora, se eu vou executar este script, você verá erro, você verá erro, promessa falhou e tratou aviso de rejeição de promessa e nota importante aqui que isso então chamada de volta nunca foi acionada porque a promessa rejeitada e não vemos nenhum valor de resultados. Isso significa que a promessa lança um erro e não fazemos nada para lidar com isso. Sempre tente detectar erros das Promessas. Isso é realmente importante porque, caso contrário, você verá mensagens como aquela rejeição de promessa não tratada, o que pode potencialmente travar o aplicativo. Então, para capturar essa rejeição dentro da promessa, temos que usar o bloco de captura que vimos anteriormente. Então, vou colocar o DOD e depois vou chamar o método catch. E por dentro eu também tenho que passar um retorno de chamada, pois o primeiro argumento que chama volta para o método catch receberá o que rejeitarmos essa promessa. Então, como rejeitamos essa promessa com outro objeto, nova promessa falhou. Aqui. Primeiro argumento, vou receber o objeto. Então, vou apenas para o log do console. E direi que o adder ocorreu. E então vou imprimir a mensagem de erro. Ótimo, vamos tentar executar o arquivo. Você verá que não temos nenhum aviso de rejeição de promessa não tratado. E desta vez vemos nosso registro do console. Assim, sempre que rejeitarmos a promessa, toda a dança que definimos para resolver a partir dessa promessa nunca será executada porque a promessa lança um erro e esse erro ou rejeição é tratado pelo bloco catch. Outra ótima dica sobre promessas é aquela dança de pontos. Eles podem ser acorrentados quantas vezes quisermos, o mesmo com blocos de captura. Então, por exemplo, se aqui eu vou colocar outro ponto novamente, você verá o esboço inteligente finalmente. E, novamente, chamo o método then, passo a chamada de volta. Desta vez, recebi valor, digamos, e eu tento consolar o valor de log em segundo deles. E você pode adivinhar qual será esse valor? Vamos tentar. E vemos que uma promessa falhou. Aha, ok, Então, em vez de rejeitar, vamos novamente usar o resolve para realmente dizer dar o controle para dançar pontos. Não precisamos lançar o adder dessa promessa desta vez. Então observe o arquivo GS, você pode ver o Hello primeiro impresso porque isso é o que fazemos na primeira chamada de volta e depois vemos que o valor no segundo Dan é indefinido. A coisa é que quando você encadeia múltiplos e argumentos, o primeiro argumento no Dan subsequente será o valor de retorno do anterior, porque a partir deste primeiro, depois callback não garantirá nada. Segundo ponto, em seguida, o primeiro argumento será indefinido. Se eu vou devolver cinco aqui, valor aqui agora será cinco. Vamos tentar. E você verá o valor em segundos, então é de cinco anos. Então, se eu vou usar outro terceiro Duck Dan, e desta vez vamos dizer val três em terceiro, então será três, certo? Vai ser indefinido, certo? Porque a literatura nada do anterior. Então, se eu vou retornar 10, Val três vai ser 10. Espero que esteja claro. E você pode ter uma pergunta, por que precisamos encadear várias danças aqui? O problema é que, no mundo real, vamos trabalhar com várias promessas ao mesmo tempo. E dentro de uma promessa, vamos chamar outra promessa algo como fazer algum ponto então, então dentro teremos algo como retornar outra promessa e novamente, e assim por diante. É por isso que é mais fácil passar o resultado de alguma lógica para outra, a fim de simplificar o código para que ele o torne mais legível. Sei que pode ser confuso porque não há um exemplo real agora aqui. Mas acredite em mim, está totalmente bom. Você verá isso no futuro. Na verdade, vamos tentar criar um exemplo mais real usando promessas. Então, vou remover tudo isso. E, em vez disso, vamos criar uma promessa completamente nova de que vamos envolver a função setTimeout que já conhecemos. Gostaríamos de converter setTimeout para, digamos, sintaxe baseada em promessa. Por exemplo, quero criar uma função, vamos chamá-la de peso, somar. Essa função eu passaria, digamos número de milissegundos, digamos 40000 por 40 segundos. E isso vai ser uma função que retornará uma promessa. E depois dessa função, uma vez resolvida, uma vez que a promessa for resolvida, esse retorno de chamada será executado. Por exemplo, log do console, quatro segundos se passaram. É algum tipo de substituição para setTimeout, mas usando a sintaxe prometida be. Então, como somos capazes de implementar isso. Então esta é a nossa maquete. Vamos apenas comentar, e agora vamos começar a escrever a promessa. Portanto, a soma de peso é uma função que recebe um argumento, que é o número de milissegundos. Então, vou criar uma soma de peso. Como uma função de seta. Essa função recebe um tempo limite de argumento em uma bagunça como essa. E essa função retorna uma promessa, que gera nova promessa para o construtor de promessa, eu passo o retorno de chamada. E esse callback recebe dois argumentos, resultado e rejeição. Mas como não encontramos rejeição aqui, vou usar o argumento de resolução. Então agora temos que atrasar a execução de código dentro dessa promessa, podemos usar setTimeout. Então, vou ligar para SetTimeout. primeiro argumento novamente é o retorno de chamada que será acionado após número fornecido de milissegundos como um segundo argumento. E para o segundo argumento, vou passar o argumento para peso alguma função em si, tempo limite na massa. E uma vez que esses frios foguem pela culatra, vou ligar para resolver a partir dessa promessa. E é isso. Essa é a nossa implementação. Vamos comentar nosso uso dessa promessa e vamos ver como ela funciona. Arquivo de nota GS. Posso ver quatro segundos se passaram e vejo minha saída quatro segundos depois. Apenas para demonstrar a você como isso não será bloqueador, podemos realmente usar o mesmo exemplo de nossos vídeos anteriores, console de log do console 2. Não importa onde eu coloquei algum ponto promessa Dan, ele sempre será resolvido usando a sintaxe de ponto de forma não bloqueadora. Isso significa que ele sempre aparecerá depois de todo o código síncrono. Para verificar isso, novamente, talvez vamos torná-lo um pouco mais curto. Uma série 100. Você vê 12 e só então quatro segundos se passaram. E não importa se eu coloquei SetTimeout ou não aqui. Por exemplo, vou resolvê-lo sem nenhuma lógica. Sempre estará no final porque uma promessa é sempre resolvida de forma sem bloqueio. Espero que esteja claro. Agora, vamos dar uma olhada em outro exemplo do mundo real usando a API Fetch que temos disponível dentro do navegador. Se, quando o Google, eu vou digitar o espaço reservado JSON, acabo no tipo de ponto de espaço reservado JSON code.com. Quando eu rolar um pouco para baixo, você pode encontrar esta seção com um exemplo. Então, vou copiar isso e colá-lo dentro do meu script NodeJS. Se eu tentar executar o arquivo, você verá Fetch não está definido porque novamente, Fetch está disponível somente dentro do ambiente do navegador. Ele faz parte das APIs da web de navegadores. Ele não é implementado nativamente em Node.JS. É por isso que esse pedaço de código só funcionará dentro do navegador. Então eu copiei novamente, vou para o console do navegador, certo? E aqui eu executo o código. Então, vamos dividi-lo. O que está acontecendo aqui? Então, antes de tudo, o que buscado faz, nós fornecemos um URL para essa função, e essa função envia uma solicitação para esse URL e nos devolve a resposta. Essa busca de pontos é uma função que retorna uma promessa. É por isso que temos que usar a sintaxe pontual Dense para resolver essa promessa. Então, o fetch envia uma solicitação para o URL de forma sem bloqueio em segundo plano. E quando a resposta para essa solicitação estiver pronta e o navegador estiver pronto para lidar com ela, essa promessa será resolvida, essa chamada sai pela culatra e obtemos acesso ao objeto de resposta. E, como você pode ver, esse é nosso senso de carga útil para nós de volta do servidor. E esta é a promessa que estava pendente Uma vez que estava frio e uma vez resolvida com o primeiro ponto, então você vê que o estado prometido está agora cumprido. Como mencionei anteriormente, essa solicitação será processada de forma sem bloqueio. Isso significa que, se essa solicitação demorar até 10 segundos, então esse retorno de chamada dentro do primeiro ponto, Dan disparará após 10 segundos de forma sem bloqueio. Mas qual é essa resposta aqui? Vamos tentar reescrever esse exemplo um pouco. E em vez de chamar a resposta JSON, vamos apenas para o objeto de resposta console.log que temos aqui. E, como você pode ver, o objeto de resposta tem algo amigo, amigo usado cabeçalhos. Bem, esse objeto de resposta representa a resposta do servidor. E nesse objeto temos o método JSON ponto que devemos chamar nesse objeto para obter a carga no formato JSON. Então, se vamos acessar esse URL em uma guia separada, certo? Tudo isso está acontecendo como manualmente. Fazemos isso manualmente usando a caixa de pesquisa do navegador, mas para fazê-lo programaticamente, usaríamos fetch e, em seguida, chamaríamos o método JSON ponto disponível no objeto de resposta. Este, mas o método JSON também o Cerence nos é uma promessa. Mas como é uma única ação dentro dessa chamada de volta, o valor dessa promessa será resolvido automaticamente e será o valor de retorno dessa chamada de volta. O que está acontecendo aqui é que dentro do primeiro ponto , em seguida, response.data não é método chamado, essa promessa é resolvida e é retornada. A partir do primeiro ponto e depois callback porque esta é a abreviação das funções de seta, já sabemos que o valor de retorno do método Dodge JSON estará disponível como um primeiro argumento no subsequente então é por isso que aqui temos argumentos chamados JSON. Você pode nomear o que quiser, e então nós apenas o console bloqueamos. É por isso que, se formos executar esse exemplo, veremos nossa carga útil. Mas desta vez fizemos isso programaticamente em vez de ir ao navegador e apenas acessar o Euro. Agora tudo isso acontece programaticamente usando a API Fetch disponível no navegador. Ótimo. Eu diria que isso é tudo sobre promessas, mas há mais uma coisa. Também temos algo chamado async await. E async await é apenas uma sintaxe alternativa à sintaxe ponto e depois, já que vamos trabalhar com múltiplas promessas ao mesmo tempo, a sintaxe de ponto ponto se torna realmente confusa em algum momento. É por isso que uma alternativa a essa sintaxe é assíncrona aguardar. Vamos ver como ele se parece, e vamos realmente tentar reescrever este exemplo com fetch usando async await. Então, antes de tudo, a sintaxe async await está disponível apenas dentro de uma função. Isso significa que, para usá-lo, temos que criar uma função. Então, vou criar uma nova função. Vamos chamá-lo de solicitação de envio. E para tornar a sintaxe assíncrona aguardar disponível dentro dessa função, temos que marcar essa função como um coletor. Então, função assíncrona enviar solicitação, se fosse uma função de seta, Const, digamos enviar solicitação. Seria assim. Logo antes da função de seta, colocaríamos a palavra-chave assíncrona, mas vamos manter a sintaxe da função regular para sabermos disso. Para resolver essa promessa, certo, temos que chamar o ponto Dan e fornecer um retorno de chamada dentro da sintaxe async await. Não usamos ponto, então usamos a palavra-chave aguardar. Aguarde. É por isso que o nome da sintaxe é chamado de async aguarda porque bem, são apenas duas palavras-chave, assíncrono para marcar função a ser usada com assíncrono, aguardar sintaxe e um peso para resolver a promessa. Só vou chamar o fetch. Deixe-me copiá-lo. Busque. E para esperar que essa promessa seja resolvida, eu tenho que colocar um peso na frente e isso substituirá o ponto, então com ele é chamado de volta na frente de uma espera, eu tenho que assinar o valor do resultado dessa promessa de sobre a Apple, por exemplo, isso vai ser resposta igual a aguardar, buscar. E o mesmo faremos com o método JSON. Então, agora temos acesso ao objeto de resposta. E então vamos criar a nova variável JSON. E ele vai aguardar ponto de resposta JSON, que está disponível no objeto de resposta. Se você não for usar a palavra-chave await, a variável JSON será o objeto promissor, assim como você viu no início do vídeo. Isso não é o que queremos. Só queremos o valor do resultado dessa promessa se eu for remover a palavra-chave await, certo? E se eu passar o mouse sobre a variável, verei promessa porque esse é o objeto promessa. Mas se eu ficar aguardado, terei algum, o que significa que essa variável manterá qualquer valor, mas definitivamente não é um objeto promessa. Agora, vamos tentar registrar o console JSON. E esse pedaço de código substituirá completamente essas três linhas. Sim, é um pouco mais de linhas, mas essa sintaxe é mais fácil de ler. A sintaxe async await é construída sobre promessas, e sua intenção é fazer promessas para se parecer mais com código síncrono regular. Porque você pode ver que podemos ler este pedaço de código linha por linha, ao contrário do ponto, então um nó a apontar aqui é a segunda linha de código, certo? linha número sete não será executada antes linha número 6 resultar, uma vez que usamos a palavra-chave await, significa que se esta linha de código, ela, essa promessa leva 10 segundos para ser executada, o código não irá mais adiante. Ele aguardará todos os dez segundos até que a promessa seja resolvida, porque usamos a palavra-chave await, ela aguarda a promessa. A promessa é resolvida e só então a execução continua. Espero que fique claro verificar se vamos chamar a função e vamos executar esse pedaço de código dentro do navegador. E você verá que teremos exatamente o mesmo resultado. Vamos ver nossa carga útil que recebemos do servidor. Tudo bem, acho que isso é tudo para este vídeo. E sei que foi muito difícil entender essa quantidade de informações. Foi muito confuso, mas acredite em mim, não é tão complicado quanto parece. Vamos anexar o tópico mais uma vez em nossos projetos React. E é aqui que te verei da próxima vez. Adeus. 33. Modos de ECMAScript: Ei, neste vídeo eu gostaria de falar sobre módulos atmosféricos no ambiente Node.JS, já sabemos que existe um sistema de módulo nativo chamado GS comum. Ele usa a sintaxe de exigência e de exportações de módulos para importar e exportar algo de um módulo no ambiente do navegador, também temos um sistema de módulo de navegador nativo que é chamado de script. Módulos e módulos atmosféricos usam sintaxe de importação e exportação. comunidade Nodejs envia módulos Ackman Script a serem implementados em Node.JS para substituir o CommonJS porque os módulos Ekman Script são mais convenientes e mais abrangentes. E, eventualmente, criamos ferramentas que nos permitem usar módulos ACML Script no ambiente Node.JS sem suporte direto para módulos atmosféricos no ambiente Node.JS, de qualquer maneira, e moderno JavaScript, você verá os módulos ECMO Script. E raramente, eu diria que você veria CommonJS. Agora, neste vídeo, gostaria de falar sobre importação e exportação de módulos atmosféricos porque há alguns aspectos importantes que precisamos entender sobre eles. Primeiro, vamos criar dois arquivos. Então, vou renomear file.js para file.js MGS para usar módulos de script ACML nativamente no ambiente Node.JS. Então vou criar um segundo arquivo chamado segundo MGS. E do segundo MGS, vou exportar algumas coisas. Então, primeiro vou criar uma variável chamada Cinco, e vou exportar cinco ao lado dela. Vou exportar const 10. E vou especificá-lo assim. Você vê a diferença? Então, primeiro criei uma variável, depois a exportei. E aqui está apenas uma linha única, basicamente a mesma coisa que no topo. Talvez vamos exportar outra coisa. Exportar const. Meu nome será Andrew. E no final, vou colocar o padrão de exportação e, desta vez, deixá-lo comprar exatamente assim. Então, como você pode ver, temos dois tipos de especialistas. Nomeamos exportações e temos uma exportação padrão. Portanto, um aqua Script módulos, existem dois tipos de especialistas nomeados e padrão. Pode haver apenas uma exportação padrão em um módulo e quantas você quiser exportações nomeadas. Agora, como podemos realmente importar todos esses. Se eu for ao File MGS aqui, preciso digitar importar algo do segundo MGS. Ótimo. Então, o que devo fornecer aqui para importar 5? Bem, o problema é que qualquer módulo tem seu próprio objeto de exportação, o objeto especialista para segundo MGS ficará assim. Então, primeiro exploramos cinco, certo? Que será nosso especialista nomeado porque bem, temos a Bíblia nomeada cinco e exportamos a variável chamada cinco. Então cinco serão cinco, então essa mesma largura, 10, e o mesmo com o meu nome. Essas são todas as nossas exportações nomeadas. Então, no final, temos a captura padrão de exportação, especialistas padrão. Eles não têm nenhum nome. Isso porque eles são padrão. Você exporta apenas um valor. Você pode ver que eu não criei nenhum nome explícito para uma string nítida, certo? Ele não é atribuído a nenhuma variável, apenas é exportado por padrão, módulos atmosféricos realmente anexarão essa exportação padrão ao objeto de exportação sob a chave padrão, assim como essa. Então, eventualmente, acabamos com um objeto como esse. Isso é o que exportamos do segundo mgs. Agora, se eu quiser importar 5, posso usar o objeto está estruturando. Por quê? Porque bem, exportamos um objeto. Então, novamente, cada módulo tem um objeto especializado e, como é um objeto, podemos usar a destruição de objetos. É por isso. Aqui ao lado de importar, vou colocar colchetes encaracolados para essa estruturação. E vou importar 5, certo, especifiquei a chave que eu queria importar 5. Além disso, gostaria de pegar talvez meu nome, cinco e meu nome. Vamos console.log cinco e meu nome. E vamos executar o script para verificar isso. E vemos cinco e Andrew. O que está correto. No entanto, e a nossa exportação padrão aqui? Vamos tentar importar o padrão. Na verdade, menos destruição padrão. Se eu fizer isso, terei instantaneamente um erro de sintaxe. O problema é que não podemos simplesmente usar essa palavra-chave padrão reservada. Isso não é permitido para importar a exportação padrão, não precisamos usar a estruturação. Em vez disso. Só temos que dar nosso próprio nome para o valor exportado. Então, deixe que seja minha vírgula de importação padrão e, em seguida, todas as exportações nomeadas. Portanto, se não precisarmos de todas as exportações nomeadas, só poderemos importar a exportação padrão, o que será nítido. Então, vou remover essa parte estruturante e manterei apenas minha importação padrão. Agora, deixe-me tentar registrar o console minha importação padrão. Você verá nítido e não importa qual nome eu forneço para minha importação padrão. Não importa porque inicialmente, ele não tem nenhum nome de variável. Ao contrário de nossos especialistas nomeados, todos eles têm um nome significativo. Nós a exportamos variável chamada cinco. É por isso que quando vamos importar essa variável, podemos renomeá-la, certo? Podemos simplesmente colocar 55 maiúsculas não existem no objeto exportado. Temos cinco, que são minúsculas. É por isso que temos que seguir rigorosamente as mesmas regras da destruição de objetos. Temos que usar os mesmos nomes que exportamos. Outro caso de uso seria quando precisássemos importar tudo isso como um único objeto. Assim como você vê aqui, não queremos separar como exportações nomeadas e exportação padrão, assim. Não queremos separá-los assim. Então, em vez disso, queríamos receber o único objeto inteiro. Portanto, neste caso, podemos importar asterix como e, em seguida, o nome do objeto. Então, deixe que seja o segundo módulo. E agora, se eu vou cancelar o segundo módulo de log, você verá que eu tenho, basicamente meu objeto de exportação. Tenho 5, 10, meu nome e padrão. E agora, para acessar o especialista padrão, preciso agora realmente referenciar a chave padrão, certo? Você verá afiado. Se eu precisar acessar 10, terei que usar 10. Então, o que acabamos de fazer, importamos todo o módulo para aquele único segundo módulo, tigela de massa, eu diria na prática, isso é menos comum na prática no mundo real. Na maioria das vezes, veremos uma exportação padrão ou uma exportação nomeada. Eles são muito usados no mundo real. Na verdade, vamos ver assim 510 ou se um módulo tiver apenas exportação padrão, usaríamos somente essa importação padrão. E nós o usaríamos assim. Bem, é aí que basicamente você vai vê-lo. Não é tão difícil entender essa parte. Você só precisa sempre lembrar que existem dois tipos de exportação. Uma exportação padrão e uma exportação nomeada, há apenas uma exportação padrão para um único módulo que você não pode usar para exportar o padrão aqui. Se eu tentar fazer isso, você verá que terei identificador de erro de sintaxe padrão já foi declarado. Eu recomendo que você sempre se lembre de que cada módulo tem um objeto que está sendo exportado e todas as exportações nomeadas são mescladas nesse objeto. É mais fácil lembrar que você precisa importar esse objeto. Usar objeto é estruturação. Acho que os módulos ECMO Script são divertidos e eu realmente gosto deles. E espero que o U2 o veja no próximo. 34. ECMAScript ou JavaScript: Ei, isso vai ser curto. Eu só quero esclarecer a diferença entre um script e JavaScript. Você provavelmente viu muitos termos, como ES6 é cinco, ES 2015. Depois desse vídeo, você saberá a diferença. Para procurar a resposta, usarei o Google e vou digitar o script ECMO ou GS. E o Google me dirá a diferença. Assim, como podemos ver no primeiro pop-up, a especificação de script ECMO é um blueprint para criar uma linguagem de script. E o JavaScript é uma implementação desse blueprint. E você pode ver diferentes variações dessa declaração em todos esses links. Para resumir rapidamente essa instrução, posso dizer que o script ECMO é um conjunto de cátions específicos que o JavaScript implementa. Isso significa que o roteiro AGMA é algum tipo de roteiro para um filme em que o filme é JavaScript, tão fácil quanto isso. Para obter mais informações, você pode navegar até a página da Wikipédia para o script ECMO. Então deixe-me abrir essa página e daqui podemos ver diferentes versões do acme scrape. A versão mais comum do script ACML provavelmente é sim, 2015, que se chama ES6 porque era a sexta edição do script ECMO. Se você rolar para baixo, poderá ler o que exatamente foi feito nessa versão específica. E também há um termo chamado ES. Em seguida, como você pode ver, este é um nome dinâmico que se refere a qualquer que a próxima versão inclua no momento da redação. Agora sabemos que quem se refere ao JavaScript como script ECMO é uma pessoa certa. Porque agora sabemos que esses dois são basicamente a mesma coisa. Acho que é isso. Para obter mais informações, consulte a Wikipédia ou um Google. Vejo você no próximo. 35. O que é o React?: Ei, finalmente começamos a falar sobre o react. Esses vídeos futuros curtos abordarão a teoria e os conceitos do React. Sinta-se à vontade para fazer referência a essas séries qualquer momento no futuro. Let's go React é uma biblioteca para criar interfaces de usuário. Ele pode ser usado para criar sites, aplicativos móveis e até aplicativos de desktop. A maneira mais fácil de aprender a reagir é provavelmente começar do reagir na Web para criar sites. Neste vídeo, vou falar do ponto de vista da web, o objetivo do react é criar interfaces de usuário com algo chamado componentes. Para sites, é apenas reagir ou Reagir para a web. Para aplicativos móveis, é React Native para aplicativos de desktop que é chamado de elétron. React opera somente na camada de exibição. Isso significa que o react não força sobre como você deve criar seu aplicativo. React apenas força sua própria lógica e determina como você deve manipular os elementos HTML subjacentes. O resto é sobre você no passado. Aqui, por volta de 20 e 10, jQuery foi muito usado para manipular HTML por meio de JavaScript. Mas não há necessidade de usar o jQuery hoje em dia. Como o react é apenas para a biblioteca, ele pode ser integrado qualquer aplicativo existente para criar uma interface de usuário. Exemplos de sites do React são Facebook e Netflix. Discord usa o React para tudo para criar seu site, aplicativo móvel e até mesmo o aplicativo para desktop é criado com o React. Muito impressionante, não é? React não é uma estrutura que é feita por outras partes do aplicativo, deve ser construída com outras ferramentas e bibliotecas. E você verá que, assim que entrarmos na codificação, princípio, o react foi usado para criar aplicativos de página única, apenas, sites que são totalmente gerenciados pelo JavaScript e destinados a preencher aplicativos móveis mais parecidos. Mas, por enquanto, a comunidade React, ela criou muitas ferramentas e estruturas em torno do react. Portanto, hoje em dia somos capazes de criar qualquer tipo de site com o React. Mas aí está, renderização no lado do servidor, aplicativo de página única, páginas da Web estáticas ou talvez um aplicativo híbrido. E você provavelmente viu outras soluções por aí, como Vue, JS, svelte ou talvez até Angler. Todos eles são baseados em componentes e, eventualmente, alcançam o mesmo resultado. É muito difícil dizer qual deles escolher. Algo é mais fácil. Algo é mais difícil. Se você ainda teve dificuldades com a escolha, eu recomendaria escolher aquele com nome ou logotipo mais atraente, tão simples quanto isso. Mas em nossos projetos, conheceremos o React. Fique atento porque só restam alguns vídeos teóricos antes de entrarmos na parte de codificação até a próxima. 36. Abordagem baseada em componentes: Ei, lá No vídeo anterior, mencionei componentes e abordagem baseada em componentes. Mas qual é o componente? Um componente é apenas um bloco de HTML que não pode ser reduzido no futuro. A abordagem baseada em componentes é quando um aplicativo está sendo construído com componentes, melhor pensar em um componente como uma tag HTML criada pelo usuário personalizada. Mas, além disso, os componentes também podem incluir lógica e estado. Por exemplo, um componente pode ser um botão que muda de cor. Uma vez clicado, o botão muda a cor de fundo. Podemos nomear esse componente como botão de cor. E mais tarde, em qualquer parte do código HTML, Use o botão Cor quantas vezes quisermos. Isso é basicamente o que fazemos com tags HTML. Os componentes não são diferentes. Faz sentido pensar neles como blocos de construção para o aplicativo. A abordagem baseada em componentes forma uma árvore de componentes. No topo dessa árvore, há um componente raiz que aninha outros componentes no componente raiz do React é quase sempre chamado de aplicativo, ou outros componentes são aninhados no componente do aplicativo. Os componentes que estão no topo são chamados de componentes de nível superior. Geralmente, são páginas. Componentes que aparecem mais altos na árvore são chamados de pais. Uma vez que isso está abaixo são chamados de crianças. Vamos dar uma olhada na página oficial do Facebook. Facebook é o criador do React, e é por isso que é o melhor exemplo possível a ser observado. Vou tentar dividir o espaço em componentes para lhe dar uma ideia básica, vamos. O site inteiro em si é o componente App. Na parte superior, teríamos componente Navbar e o Navbar no centro, há um componente de navegação e cada botão dentro é outro componente também. À direita, ele pode ser um componente de navegação perfilado, onde cada botão semelhante é o mesmo componente, mas reutilizado várias vezes. Experimente você mesmo e divida a lista suspensa abaixo em componentes abaixo da barra agora, pode ser um componente de página inicial. página inicial inclui três componentes. Barra lateral à esquerda, barra lateral à direita e alimentação no componente da barra lateral central inclui o menu. O componente Feed inclui a lista de postagens e a barra lateral à direita inclui outra coisa. Cabe aos desenvolvedores como estruturar e criar componentes. Certamente é possível manter toda a marcação e toda a lógica em um único componente sem criar outros componentes. Mas então a ideia de abordagem baseada em componentes seria totalmente comprometida. E será o mesmo que não usar componentes. No final do dia, acabamos com uma árvore de componentes. E essa árvore sempre tem uma direção de cima para baixo. Se houver algumas alterações em um componente pai, todos os filhos desse componente também serão afetados simplesmente porque fazem parte dele. Vamos concluir. O desenvolvimento com o React é baseado em uma abordagem baseada em componentes. aplicativo React pode ser visualizado como uma árvore de componentes. Os componentes são peças reutilizáveis do aplicativo. As vantagens dos componentes são reutilização e a consistência em toda a aplicação. Se o componente de postagem do usuário de usabilidade pode ser inserido em qualquer lugar do aplicativo era apenas uma única linha de código. Com consistência, o componente de postagem do usuário sempre se comportará exatamente da mesma forma, independentemente da página ou do local onde ele é usado. Bem, é isso. É assim que todos os aplicativos modernos são criados hoje em dia com componentes. Espero que faça sentido. Cia. 37. Funções vs, aulas: Olá, In React. Existem dois tipos de componentes disponíveis para nós, resíduos de classe e função. Eles diferem em sintaxe e na forma como manipulamos dados dentro deles. Antes do React Hooks, não tínhamos outra opção senão criar competência usando classes no presente, a situação é um pouco diferente. Com o React Hooks, usamos funções para criar componentes. ganchos React estão disponíveis apenas em componentes baseados em funções, e essa é a razão pela qual as funções simplificam os componentes. A sintaxe é mais leve e mais fácil de compreender. Em nossos projetos, usaremos o React Hooks, o que significa que vamos trabalhar com componentes baseados em funções. Somente. Componentes baseados em classe se tornam cada vez mais usados raramente. No entanto, é possível que às vezes lá fora você veja componentes baseados em classe, mas isso é totalmente bom. A equipe do React tem suas apostas no React Hooks e eles acreditam que os ganchos são o futuro. Depois de terminar o último projeto, você poderá ler componentes baseados em classe e não terá problemas na transição entre funções e classes. Espero que faça sentido. Vejo você no próximo. 38. Reagir sob a capa: Olá novamente. Vamos ver como o React funciona sob o capô. No exemplo de um aplicativo de página única, a melhor maneira de pensar em um aplicativo React como se fosse uma árvore de componentes no React, há uma coisa chamada ponto de montagem em que o aplicativo React está sendo inserido, ou melhor dizer, montado por padrão, é uma tag div com ID rude. Na parte superior da árvore, há o componente do aplicativo, que é o invólucro para todos os componentes do aplicativo. Dentro do componente do aplicativo, existem componentes de nível superior. Dentro deles, coloque componentes aninhados e assim por diante até o componente muito aninhado. Se pensássemos nisso por um momento, é praticamente o mesmo a estrutura HTML DOM, não é? O Document Object Model ou DOM é a representação da página HTML na forma de uma árvore de tags. Dom é como os navegadores veem e interpretam a marcação HTML. Quando fazemos coisas básicas em JavaScript como Document.getElementByID id id. Esse objeto de documento faz parte da API DOM que é exposta pelo navegador. React cria na memória representação da árvore de componentes chamada DOM virtual. É o mesmo que o DOM do navegador, mas é usado apenas internamente pelo react. Quando o aplicativo React que está sendo renderizado na árvore de componentes de página está sendo traduzido da apresentação dominante virtual para marcação HTML. Essa marcação HTML está sendo inserida no elemento de montagem na página da Web. Lembre-se de que tudo isso é feito por meio de JavaScript. Quando os dados são componentes precisam ser atualizados, react sempre opera com o DOM virtual em primeiro lugar. Ele toma o estado capturado anteriormente do DOM virtual, o compara ao recém-criado com atualizações e calcula a diferença. Se houver alguma diferença, react calcula quais dados e componentes devem ser atualizados. E essas alterações são chamadas de renderizações 3D. Cada renderização basicamente representa estado DOM virtual em um momento, o processo de cálculo da diferença entre renderizações é chamado de reconciliação. E o nome do algoritmo desse processo é React Fiber. Em termos simples, o React Fiber detecta o que deve ser atualizado entre as renderizações. Você pode ter uma pergunta, por que usar o DOM virtual? Não está adicionando um passo extra e mais complexidade? Bem, isso depende. DOM virtual muda ou mais leve porque estão todos na memória, ao contrário das alterações em um DOM real, quando a marcação HTML é alterada, navegadores geralmente recalculam o layout e repintam a página da Web. É melhor ter 100 atualizações no DOM virtual, que eventualmente resultará em uma única atualização real do dom e repintura de patch maior do que aplicar todas as 100 atualizações diretamente no DOM real. Quando navegamos por um site sob o capô, o HTML é constantemente atualizado. React garante que essas atualizações sejam feitas da maneira mais eficiente possível. A ideia por trás da cúpula virtual é reduzir o número de atualizações reais do DOM. Sei que pode ser difícil perceber essa quantidade de informações, mas está totalmente bem. Você não precisa saber todos os detalhes. Agora, sabemos como o React funciona internamente. Essa é aquela em que uma peça faltante sobre sua arquitetura, essas ervilhas é um fluxo de dados unidirecional, que é chamado de fluxo. Flux é o nome de uma arquitetura interna reage. Flux implica que os dados no aplicativo sempre fluem em uma direção de cima para baixo. Por exemplo, quando os dados dentro de um componente são atualizados, o componente e todos os seus filhos também são renderizados. Caso as crianças sejam atualizadas ou não, é o trabalho para o React Fiber mencionado anteriormente, o algoritmo que calcula exatamente o que precisa ser atualizado. Mas o fato é que as atualizações se movem de componentes pais para filhos. É impossível ter o fluxo de dados indo de baixo para cima. Acho que você será capaz de sentir isso quando escrevermos código React. Tudo bem, vamos resumir sob o capô, o react usa sua própria representação HTML DOM chamada DOM virtual. O objetivo do DOM virtual é reduzir o número de atualizações reais do DOM. O algoritmo principal do React é chamado React Fiber e sua principal tarefa é calcular o que exatamente deve ser atualizado entre os re-renderizadores react arquitetura design é chamado de fluxo, o que implica os fluxos de dados apenas em uma direção de componentes pais para filhos. Bem, esta é toda a informação sobre o React. Não se preocupe se isso foi confuso. Basta assistir novamente o vídeo ou procurar mais informações, se necessário. Vejo você em seguida. 39. Placas e Bundlers: Ei, desta vez eu gostaria de falar sobre como podemos começar o desenvolvimento de um novo React Web App. Neste vídeo, não considerarei plataformas online diferentes, como o CodePen, para desenvolver diretamente dentro do navegador. Porque essas plataformas são usadas apenas como playgrounds, ou geralmente apenas para compartilhar rapidamente o código com a configuração básica. Para entender como os aplicativos JavaScript modernos estão sendo construídos, devemos entender o que nosso projeto Butler é um projeto Bundler é uma ferramenta que leva todo o código-fonte, scripts, estilos, imagens, processos, tudo isso, e crie um projeto construído. O projeto construído é uma versão minificada do código-fonte otimizada para máxima eficiência. São toneladas de som do projeto Bundler são os mais comuns são Webpack, roll up e parcel. Todos os projetos JavaScript modernos são cobertos por essas ferramentas. Ótimo, vamos voltar à nossa pergunta principal, maneiras de começar a desenvolver um novo aplicativo React. Eventualmente se resume a três passagens. A primeira maneira de criar um aplicativo React é configurar e configurar todas as ferramentas de compilação, como o pacote da web para React do zero. A segunda maneira é usar um modelo de projeto. Criamos ferramentas já configuradas para o desenvolvimento do React. E a terceira maneira é usar uma estrutura do React, como o próximo GS ou o Gatsby. Não há resposta correta sobre qual escolher. Tudo depende da configuração que você está procurando, preferências pessoais, recursos especiais e assim por diante. Configurar tudo manualmente e configurar o Butler do projeto, como o Webpack do zero, raramente é visto hoje em dia. Quase toda vez que você usaria um modelo ou uma estrutura. modelos, a propósito, são muitas vezes chamados de caldeiras, o que significa que sempre que você vê onde a placa de caldeiraria não surta, é apenas outra maneira de dizer o modelo de palavra. Existem muitas placas de caldeiras do projeto React criadas pela comunidade diferentes , que são copiar um modelo e começar a desenvolver nada mais necessário. O boilerplate React mais conhecido provavelmente é o aplicativo Create React, que é mantido pela equipe do React sob o capô, ele usa configuração de web back predefinida. Você pode se sentir tentado a usar somente o aplicativo Create React. Mas é importante lembrar que o aplicativo Create React não é a única maneira de desenvolver aplicativos React no presente, existem muitas ótimas alternativas. Atualmente, ferramentas construídas bastante populares para front-end são VDD e snowpack. Outra maneira de lidar com o React é usar uma estrutura do React. Frameworks são super populares agora, especialmente em seguida, sim, mas eu diria que é melhor começar a aprender reagir sem uma estrutura. Como estruturas para recursos e funções específicas da estrutura CHES em nossos projetos, usaremos modelos já configurados e colinas construídas. Quais? Sente-se assim que entrar nos projetos, veja outro 40. 1 visão geral do projeto TicTacToe: Olá, pessoal. Bem-vindo à seção Tic Tac Toe. Este será um rápido vídeo de introdução onde você poderá visualizar o projeto. O projeto será o jogo Tic Tac Toe, que você pode ver na tela agora mesmo. Podemos clicar nos quadrados. Nós podemos jogar o jogo. Sempre que tivermos um vencedor, a combinação vencedora será destacada. Teremos efeitos ativos diferentes. Além disso, na parte inferior, estará a história do jogo , que podemos percorrer e ver quais movimentos foram Se clicarmos nos quadrados, poderemos sobrescrever o histórico caso precisemos do botão de início do jogo, e eu diria que é basicamente isso. Embora possa parecer simples. Ele tem muitos conceitos básicos que criarão uma boa base para seu conhecimento de reação. Então, vamos começar. 41. 2 Criando e configurando novo projeto com o Vite: Olá. Finalmente vamos começar a construir o primeiro projeto que será o Tic Tac Toe. A ferramenta que vamos usar para construir o Tic Tac Toe será o Vite. Este é o site oficial da Vite que você pode ver agora. Você pode encontrá-lo no Google. Vou clicar em “Começar” e vamos ver o que exatamente o Vite faz. Basicamente, o Vite é uma ferramenta de front-end que constrói o projeto. Pode ser qualquer coisa. Pode ser react, pode ser JavaScript bruto ou pode ser qualquer outra estrutura compatível. Sob o capô, o Vite usa o Rollup. Rollup é um empacotador de módulos. Rollup é basicamente a ferramenta que constrói o projeto e o Vite é a configuração em torno do Rollup. Vite é muito rápido e, na verdade, muito popular no momento. Vamos examinar a documentação e começar a organizar seu projeto da primeira semana. Isso exige que tenhamos a versão 14 e superior do Node, mas tenho certeza de que você tem versão estável mais recente , que é 18 no momento. Podemos ver que podemos criar um novo projeto com npm simplesmente executando esse comando. Vou copiar esse comando e vou para o CMD. Em todos os projetos, vou usar o Git Bash e, dentro do VS Code, vou usar o Git Bash. No entanto, para este, vou usar o CMD. Você pode usar qualquer outra concha. Eu escolho o CMD especificamente porque o Vite nos fará algumas perguntas e, quando Git Bash é executado como uma instância separada, ele tem problemas de interatividade, ao contrário do CMD. Depois de executar esse comando, o Vite me fará algumas perguntas e, em seguida, criarei uma nova pasta do projeto. No entanto, vou criar uma nova pasta de projeto dentro de nossa navegação atual do terminal. No momento, dentro do CMD, eu navego para ver meu nome de usuário. Esta é a pasta do usuário e, uma vez que eu execute o comando Vite, ele criará a pasta do projeto aqui dentro desse diretório. Eu não quero fazer isso. Quero definir o caminho da pasta do meu próprio projeto. Para isso, primeiro preciso decidir onde gostaria de colocar meu projeto. Para mim, vai estar aqui dentro do D_web. Este é o lugar onde eu gostaria de colocar meu projeto. Primeiro, preciso navegar dentro do terminal até essa pasta. Dentro do CMD, vou digitar o nome do disco para mudar a navegação para o disco D. Se você estiver dentro do Git Bash, então você tem que digitar cd d e dois pontos, se você estiver dentro de qualquer outro shell, então eu tenho certeza que gosto do shell Linux , como o Bash, ou talvez no Mac, tenho certeza de que você nem precisa disso. De qualquer forma, estou dentro do disco D, depois vou digitar cd, cd significa mudar diretório e vou digitar cd_web. Eu sei que é _web porque se eu digitar ls, ls é um comando shell do Unix para listar todas as pastas dentro da navegação atual. No entanto, como o CMD é um terminal baseado em Windows, eu preciso usar dir, então dir é a alternativa de comando a menos dentro do Windows Power Terminal. Dentro de D, eu tenho _web. É exatamente por isso que eu navego, então vou digitar cd_web e boom, agora estou dentro dessa pasta e estou seguro para executar o comando Vite. Vou executar o comando copiado. Ele me pediu um nome de projeto, vamos chamá-lo de tictactoe-vite. Eu pressiono “Enter”. Agora eu preciso selecionar uma estrutura. Vamos escolher react e a variante será JavaScript. Ótimo. Agora, o comando foi bem-sucedido. Diz que o projeto de andaime em _web tictactoe-vite, concluído. Agora execute cd, npm install, npm run dev. Vamos fazer isso no departamento. Vamos sair disso. Agora, o que vou fazer abrir o arquivo VS Code, abrir a pasta e agora vou até D web e selecionar tictactoe-vite como a pasta do projeto dentro do VS Code. Quando entramos, temos alguns arquivos aqui. A primeira coisa que vamos fazer é instalar dependências. Nós temos os arquivos criados. Já temos o pacote json com algumas dependências listadas, mas não temos nenhuma delas instalada. Para isso, vou abrir o terminal integrado dentro do VS Code, e aqui o que vou fazer, vou instalar dependências executando npm install. O Npm instalado sem nenhum argumento, ele verifica o pacote json dentro da navegação atual. Minha navegação atual é a pasta tictactoe-vite. Ele procura o pacote json. Ele procura dependências e dependências de desenvolvimento listadas nela e, se estiverem ausentes, se estiverem desinstaladas, npm as instalará. Vou escrever esse comando e vou esperar. Enquanto isso funciona, vamos ver que tipo de dependências temos aqui. Por padrão, temos as dependências react e react-dom instaladas. Esses são pacotes principais do react, então react é o pacote principal e react-dom é o pacote principal especificamente para a web porque, bem, web usa o modelo dom. Dentro das dependências de desenvolvimento, temos os tipos react, na verdade não precisamos deles nos tipos react-dom. Isso é algo para TypeScript. Não sei por que eles vêm. Então, temos o vitejs plugin-react e o próprio Vite como ferramenta. Também vemos viteconfig.js aqui. Como o Vite pode ser usado para construir qualquer projeto de front-end, ele deve ser detectado. Em primeiro lugar, o Vite vem com configuração quase zero. Precisamos especificar, precisamos configurar com, ok, pegue meus arquivos de reação e, por favor, faça a mágica, e o Vite fará. Para isso, precisamos instalar o plugin, bem, que já está instalado e, dentro do viteconfig, temos que listar esse plugin do Vite aqui. Você vê que tudo já está configurado para nós. Nós realmente não precisamos fazer nada. Se você quiser ler mais sobre a configuração do Vite, siga esse link aqui. É bem simples. partir de agora, se eu abrir meu terminal novamente você poderá ver pacotes adicionados, tudo está ótimo. Mais duas coisas aparecem aqui, módulos package-lockjson e node. Portanto, package-lockjson representa a versão que acabamos de instalar. Ele captura a versão específica do pacote que instalamos. Então, temos módulos de nós. Os módulos do Node são o local onde todas as nossas dependências foram instaladas. Como temos essa pasta, agora podemos executar facilmente nossos scripts e eles funcionarão. Antes de fazermos isso, vamos configurar mais algumas coisas aqui. Vamos adicionar eslint e prettier ao nosso projeto. Para fazer isso, precisamos instalá-los primeiro. Vou executar o npm install dash dash save-dev. Save-dev instruirá o npm install a instalar os pacotes como dependências do desenvolvedor, então npm install eslint e prettier. Em seguida, precisamos criar arquivos de configuração para esses dois. Você pode ver que, quando o comando termina, eu faço com que prettier e eslint apareçam como dependências do desenvolvedor no pacote json. Vou criar um novo arquivo.prettierrc e o outro será.eslintrc. Agora, como vamos configurar esses dois? Temos algo chamado Gist. Este link será compartilhado com você. Dentro desse Gist, você pode encontrar arquivos.eslintrc e.prettierrc. Essas são as configurações que vamos usar. Vamos copiá-lo daqui e colá-lo desse jeito. Você pode escolher qualquer configuração mais bonita que desejar. Essa é apenas minha preferência pessoal que escolhi especificamente para este projeto. Você pode alterar qualquer valor de acordo com suas necessidades. Então eslint config, eu também copiei de lá. No entanto, é mais interessante do que mais bonito. Aqui fazemos algumas coisas. Estendemos o eslint recomendado, que é a configuração incorporada ao eslint. Não precisamos instalá-lo. Em seguida, estendemos o tempo de execução do plug-in, react, recommended e plug-in react JSX, além de mais bonito. Na verdade, eles vêm dos pacotes, então esses pacotes devem ser instalados. Se voltarmos a esse Gist aqui, podemos encontrar dependências de desenvolvedor, MD, eslint-config-prettier e eslint-plugin-react. Se formos até aqui, precisamos instalá-los primeiro. Esses são os plug-ins que estendemos e eles não aparecem do nada. Eles precisam ser instalados. Vou apenas copiar o comando de instalação do eslint-plugin-react e instalá-lo. Exatamente o mesmo que farei com eslint-config-prettier. O que esses dois estão fazendo? O eslint-config-prettier garantirá que nossa configuração eslint e configuração mais bonita não colidam uma com a outra. Este pacote apenas garante que não tenhamos nenhum mal-entendido entre essas duas ferramentas. O ESlint-plugin-react é um pacote bastante popular. Bem, basicamente uma lista de regras para projetos de linting react. A configuração que temos aqui abaixo, eu basicamente a retirei da documentação da página eslint-plugin-react. Você pode encontrá-lo aqui. Expandimos duas coisas desse plug-in conjunto recomendado de regras e o tempo de execução do JSX. Tempo de execução do JSX, vamos voltar a isso, o que é exatamente isso. Regras do Insights, eu desativei a regra dos tipos react prop, que vem do pacote plugin-react. A razão para esses tipos de adereços é algo que não vamos abordar. No entanto, ele está incluído aqui, então nós realmente não precisamos dele. Isso só vai atrapalhar nosso processo de desenvolvimento, então simplesmente desativamos essa regra completamente e a desligamos. O resto é como eu te disse, foi tirado daqui. Ótimo. Finalmente, talvez tentemos executar o projeto. Dentro dos scripts, temos três scripts definidos por padrão: dev, build e preview. O Dev executará o servidor de desenvolvimento local, construirá o projeto e fará uma prévia. Tenho certeza de que ele pré-visualizará a versão final de produção para nós. Ele servirá os arquivos de compilação de produção. Vamos executar o script de desenvolvimento, npm run dev. Depois de um segundo, você verá essa mensagem. Agora, podemos realmente acessar esse URL que nos permite abri-lo dentro do navegador. Se eu for até aqui, você verá isso. Bem, este é o nosso aplicativo React no momento. O que ele fez nesse caso foi criar um servidor local para nós e nos expôs o link que podemos usar para acessar o servidor de desenvolvimento. Este é o lugar onde podemos ver o projeto localmente e desenvolvê-lo. Vamos parar o comando pressionando Control C várias vezes. Vamos testar e ver a compilação do outro comando. Se eu for usar o npm run build, você verá algumas coisas aqui. Vite cria a pasta dist e, dentro da pasta dist, cria SVG, HTML e, dentro dos ativos, cria arquivos JS e CSS. O que esse comando faz é pegar todos os arquivos dentro da pasta de origem e os criar em HTML, CSS, JavaScript e arquivos secundários. Esse comando de compilação produz versão final de produção do nosso aplicativo. Posteriormente, podemos pegar a pasta dist e implantá-la na hospedagem. Isso é exatamente o que faremos mais tarde neste projeto. Nós realmente não precisamos inspecionar nada dentro da poeira. É otimizado, é minimizado e você pode ver que parece feio. Isso é totalmente bom porque deveria ser otimizado dessa maneira. Novamente, sob o capô, o vite usa enrolamento. O roll-up é a ferramenta que faz toda essa minificação, transpilação e o resto. Agora, vamos dar uma olhada, o que temos aqui entre outros arquivos? A pasta de origem é a pasta em que criaremos nossos arquivos de origem. Todos os componentes do React, todo o código vai para o código-fonte. O resto da configuração, eslint, mais bonita, que não faz parte do código-fonte, mas faz parte da configuração do projeto, está localizada na pasta raiz aqui ao lado do pacote Jason. Além disso, temos HTML de índice aqui. Indexe HTML aqui, esse será nosso ponto de entrada. É aqui que nosso projeto começa. Voltaremos a isso mais tarde. O que vamos fazer agora é não tocar em nada. Vamos abordar isso no próximo vídeo. Por enquanto, vamos dar uma visão geral do resto. Temos a pasta pública e temos a pasta de origem. A pasta pública é o local para os ativos estáticos do nosso projeto. Eles são sempre servidos sob o caminho raiz do nosso aplicativo. O que quero dizer é que vamos executar o comando dev novamente. Se vamos acessar, vamos ver o que temos em público. Temos vite SVG, então se vamos acessar a barra, que é root vite SVG, vemos que o arquivo está sendo servido aqui em vite SVG, então o caminho que você tem para o arquivo dentro pasta pública é mapeado para o segmento de URL. Se eu vou criar uma pasta, vamos chamá-la. Não sei, lol e podemos mover o vite para dentro do lol, então vite SVG será servido em lolvite.svg. Esse é o local para arquivos que não deveriam ser transpirados, minimizados ou afetados pela ferramenta de construção. Eles permanecerão como estão aqui em público, e podemos referenciá-los em nosso aplicativo. A pasta pública é bastante comum todos os projetos de front-end. Ótimo. Agora que sabemos o que são todos esses arquivos, só há uma coisa que queremos fazer antes iniciar o desenvolvimento e investigar esses arquivos. Queremos apresentar o Git ao nosso projeto. O que precisamos fazer, primeiro precisamos inicializar, o Git aqui. Dentro do terminal, vamos digitar git init e aqui você pode ver que o Git agora está presente, então o que podemos fazer é adicionar tudo isso ao palco e depois confirmar tudo. Apenas uma nota aqui. Há um novo arquivo aqui chamado Gitignore. Gitignore é o arquivo reconhecido pelo sistema Git e tudo o que está listado dentro do Gitignore será ignorado pelo Git. Dentro dessa pasta, temos muitos arquivos secundários com os quais realmente não nos importamos. No entanto, também temos aqui módulos node e dist. Esses dois serão ignorados pelo Git e, se você ver dentro do código do VS, eles nem serão destacados. O que isso significa? Isso significa que, quando enviarmos arquivos, todos os arquivos afetados serão adicionados como parte do projeto Git, mas os arquivos listados aqui não serão reconhecidos pelo Git. Eles serão simplesmente ignorados e esses módulos de nós serão ignorados porque, bem, nós realmente não precisamos deles. Esses são arquivos gerados dinamicamente. Se quisermos, digamos, compartilhar nosso projeto com outra pessoa, a pessoa que baixar todos os arquivos do projeto não terá esses módulos e nós porque pesam muito e ela realmente não precisa deles todos os arquivos do projeto não terá esses módulos e nós porque pesam muito porque podem ser criados dinamicamente. Vou apenas digitar npm install, os módulos do Node serão recriados. Vou digitar npm run build e a pasta dist será recriada. Na verdade, não precisamos muito do peso deles, e eles podem ser criados dinamicamente. É por isso que eles estão listados no Gitignore. Vamos adicionar tudo ao estado de estágio com o git add dot, para que possamos ver vários avisos aqui. Às vezes, está totalmente bem. O Git garante que nosso projeto seja multiplataforma entre diferentes sistemas que têm codificações diferentes, então não precisamos nos preocupar com isso. Depois disso, confirmamos todos esses arquivos estádios com a primeira mensagem de confirmação e, se digitarmos git log, vemos que temos o primeiro commit aqui. Incrível. Agora, precisamos fazer o upload desse projeto Git para o GitHub. O que vamos fazer é ir aqui para o GitHub. Vamos clicar em Novo repositório aqui. Nome do repositório, vamos ficar com o jogo TicTactoe-Game. Vou escolher esse repositório para ser público. Vou torná-lo público mais tarde, quando terminarmos isso, não precisamos de nenhum arquivo ReadMe inicializado com o novo repositório porque vamos criá-lo nós mesmos mais tarde, ou talvez possamos fazer isso agora, então vou criar um novo arquivo chamado README.md e, por dentro, vou usar a sintaxe Markdown. Essa é a sintaxe dos documentos, então vou adicionar hashtags aqui. Não pense muito nisso. Vamos chamá-lo de jogo Tic Tac Toe. Eu o salvo e, como é um arquivo novo, precisamos novamente adicionar outro commit. Adicionado, README.md. Perfeito. Agora temos dois commits. Ótimo. Não precisamos do ReadMe, não precisamos do Gitignore porque já temos o Gitignore adicionado automaticamente até o momento. Não precisamos de nenhuma licença. Eu clico em Criar repositório. Ótimo. Aqui dentro da configuração agora eu posso configurar e posso realmente associar meu repositório recém-criado no GitHub ao meu repositório local no meu computador. Podemos seguir as instruções aqui. Se estivermos criando um repositório completamente novo, se não tivermos nenhum arquivo, mas esse não é o caso. Precisamos escolher empurrar uma linha comum de frente de um repositório existente. Vou apenas copiar linha por linha aqui. Git remoto na origem. Depois de fazer isso, depois disso, posso digitar git remote-v e vou ver que, na origem do alias, tenho esse repositório e, se eu copiar esse link e abrir em uma nova guia, ele me levará até aqui, que significa que o link está correto. Em seguida, sugere que digitemos git Branch-m main. Eu não acho que vamos fazer isso. O problema com o GitHub e Git Community é que eles não conseguem decidir qual é o melhor nome para a ramificação principal padrão. Bem, geralmente ela é chamada de master. Atualmente, estamos na filial principal, mas as pessoas querem simplificar as coisas. Em vez de dominar, algumas pessoas querem ver o principal. Vamos ficar com o Mestre. Afinal, isso não é grande coisa. O que vamos fazer é que agora associamos o projeto ao repositório remoto, que fará o upload para o GitHub digitando git push origin master. Origin é o alias que aponta para o repositório e master é o nome da ramificação de destino no repositório para onde vamos enviar nosso código atual. Eu faço esse comando. Você pode ver que algo aconteceu e se eu for atualizar a página aqui, vou ver todos os projetos aqui e o arquivo ReadMe que criamos. Algo parecido. Parabéns a todos. Criamos e configuramos os projetos Tic Tac Toe. Nos vemos no próximo vídeo. Finalmente, começaremos a criar o aplicativo e poderemos ver quais são os componentes. Tchau tchau. 42. 3 extensões Eslint e Prettier: Olá, aqui está apenas um lembrete rápido sobre ESLint e Prettier. Como queremos ter certeza de que essas ferramentas estão integradas ao nosso VS Code e vemos tudo em tempo real, vemos os destaques e formamos um arquivo ao salvá-los, precisamos garantir que as extensões estejam instaladas. Vá até a parada de extensão aqui e certifique-se de ter a extensão do formatador de código Prettier instalada aqui, bem como a extensão ESLint. extensão ESLint garantirá que você destaque quaisquer problemas de ESLint, portanto, avisos ou erros que tenhamos no código, a extensão cuidará disso. extensão Prettier garantirá que os arquivos sejam formatados de acordo com o conflito quando estiverem seguros. No entanto, para a configuração do Prettier, precisamos de um pouco mais de configuração, para isso, você precisa acessar as configurações JSON no VS Code. Abra as configurações do usuário JSON e, aqui dentro, queremos ter certeza que temos o formato do editor em save true, bem como o formatador padrão do editor e o JavaScript, formatador padrão do editor. Tudo isso está descrito na página Extensões. Basta abrir essa página diretamente no código VS, basta percorrer, copiá-la, bem como copiar o formato do editor salvá-la e colocá-la dentro suas configurações JSON, assim mesmo. Depois disso, quando você salvar os arquivos, eles serão autoformativos. Para a extensão ESLint, não precisamos de nenhuma configuração, ela simplesmente funcionará. Te vejo. 43. 04 O que são componentes e adereços do Reagir: Olá a todos, vamos finalmente descobrir o que temos dentro da pasta de origem. Vamos primeiro ver como o Vite resolve tudo para a pasta de origem. Se eu vou executar o npm run dev , o Vite serve o servidor de desenvolvimento e nós temos isso. Tudo isso é criado e definido dentro da fonte. Mas como a Vite realmente resolve isso? Se olharmos dentro do package.json e examinarmos o script dev, o script dev, o que ele realmente faz, ele apenas chama o comando Vite. No entanto, um argumento opcional para o comando Vite é o caminho para index.html, que serve como entrada para que o Vite entenda que, ei, esse é o nosso ponto de entrada. O Index.html que temos aqui é a entrada e, por padrão, quando o Vite é chamado sem nenhum argumento, ele procura index.html dentro da pasta atual, o que está correto em nosso caso. Dentro do index.html, temos uma marcação simples, então o Vite resulta nesse index.html assim que o comando é iniciado, e ele vê que, ok, dentro do index.html, temos um script que aponta para a fonte main.jsx. Source main.jsx é o ponto de entrada para o aplicativo React, enquanto index.html é o ponto para o próprio aplicativo. Bem, em um aplicativo, você pode realmente ter vários aplicativos React, mas isso raramente é visto. Temos um script que aponta para main.jsx. Temos um desenvolvedor com o ID definido como root, e temos ataques de meta bastante padrão aqui. Na verdade, podemos mudá-lo e chamá-lo de Tic Tac Toe. Depois de salvá-lo, você pode ver no terminal que ele foi alterado para página para carregamento. Se eu voltar, ele será carregado automaticamente para mim. Eu não pressionei nada e o título foi alterado. Muito incrível, não é? Se olharmos para dentro, fonte main.jsx. Aqui, finalmente conhecemos o React. Temos algumas coisas importadas do React e do react-dom/client. Essa importação do React do React, antes do React 17, era necessária em todos os arquivos em que você escreve o código React. No entanto, a partir do React 18, isso é desnecessário. Você pode omitir a importação no React. Mas no nosso caso, como usamos o namespace React para usar o modo estrito, ainda precisamos importá-lo apenas aqui, mas em todos os outros arquivos, não precisamos digitar import React from React. Isso foi necessário novamente somente antes do React 17. Dentro do eslintrc, temos plugin jsx-runtime para configurar o eslint para entender que estamos usando o React 18. Por favor, não nos diga que precisamos importar o React do React. Eslint sabe disso. Importamos o ReactDOM e, no objeto ReactDOM, chamamos createRoot. Para o método createRoot, passamos elemento de obtenção do documento por ID root. Pegamos o elemento do index.html, que é apenas um elemento vazio, e esse elemento vazio é chamado de ponto de montagem. Esse é apenas o elemento vazio. Pode ser qualquer elemento HTML válido que deve estar presente dentro do HTML. Ele servirá como recipiente para o aplicativo React. Para a árvore de componentes. Criamos raiz a partir desse elemento HTML. Nós o obtemos novamente em index.html, os IDs devem corresponder se eu for digitar algo diferente que não corresponda à raiz, defina um index.html. Nada será criado na página. Bem, isso é óbvio. Ótimo. Nós o colocamos de volta à raiz e garantimos que tudo funciona. Uma vez que temos o objeto raiz, no objeto raiz, chamamos o método render. Para o método render, precisamos passar a árvore de componentes que queremos que esteja presente na página. Bem, para o método de renderização, basicamente passamos nosso aplicativo React, nossos componentes React. O componente App quase sempre representa os principais componentes dentro do aplicativo React. Quase sempre, tenho certeza, é chamado apenas de App. React StrictMode, é algo que foi introduzido recentemente no React. Ele também vem como um componente, mas o que ele faz é apenas algumas coisas que nos alertarão sobre possíveis problemas ou erros que possamos ter no aplicativo React. Nós apenas mantemos isso assim. Não mudamos nada aqui. O que você vê aqui é nossa árvore de componentes, sem mais nem menos. Todos os componentes sempre começam com uma letra maiúscula. Você não verá um único componente que comece com uma letra minúscula. Isso é impossível. A primeira regra de ouro é que os componentes estão sempre em maiúsculas. Sempre, não importa o que aconteça. Temos o modo React StrictMode e o componente App, e essa é nossa árvore de componentes. Agora, vamos finalmente dar uma olhada no componente App. Dentro do componente App , meu Deus, já temos alguma coisa. Se passarmos o mouse, podemos ver qualquer erro de eslint proveniente da regra em branco de destino react/jsx-no. Bem, tudo bem não vamos fazer nada sobre isso, vamos apenas remover essa marcação de qualquer maneira , então não nos importamos. Isso é bom. Esse eslint nos diz que não é seguro manter as tags Anchor sem atributos específicos. Perfeito. Então, simplesmente não o tocamos. Isso é um componente. função do aplicativo que você vê aqui é um componente chamado App, então é um componente do aplicativo e já temos algumas coisas criadas aqui, mas vamos removê-las, não precisamos delas. Vou remover isso, vou remover algo que você disse e sobre o qual não sabemos nada, logotipo do React, App.css. Talvez possamos manter o App.css. Podemos então remover o resto. Em vez disso, podemos simplesmente digitar olá remover o nome da classe. Temos um único div, olá e fechamos div, nós o salvamos. Em seguida, vamos remover a pasta de ativos. Não precisamos disso. Vamos remover o index.css. Não precisamos dele dentro do main.jsx. Vamos remover a referência ao index.css, pois acabamos de remover esse arquivo. Temos apenas main.jsx, que importa o componente App, e dentro do componente App temos o App.css. Ótimo. Um componente é apenas uma função que retorna a marcação JSX. O que você vê aqui é HTML, mas, na realidade, nos bastidores, ele é traduzido para JavaScript. Tudo o que você escreve aqui é JavaScript. Essa marcação HTML aqui é chamada de JSX. Se eu não estiver errado e se me lembro corretamente, é a combinação de JavaScript e XML, não tenho certeza disso, mas de qualquer forma, essa marcação é chamada de JSX. Se você puder ver, também temos a extensão.jsx. Poderíamos ter usado a extensão just.js em vez de jsx, mas o fato é que, como o Vite é uma ferramenta de front-end ele também precisa detectar exatamente onde temos a marcação React e onde exatamente temos o JavaScript normal. Isso exige que nomeemos todos os nossos componentes ou todos os nossos arquivos onde temos marcação jsx com a extensão.jsx. É por isso que você vê main.jsx porque temos a marcação JSX dentro de um App.jsx, porque bem, esse é um componente e definitivamente terá uma marcação JSX interna. Novamente, um componente é apenas uma função simples que retorna a marcação JSX, que se parece com HTML e basicamente, é traduzida para JavaScript. Podemos digitar qualquer HTML válido aqui. Se eu vou digitar span tag, ou tag h1, e chamá-la de título, eu a salvo depois volto, você pode ver que ela está refletida aqui. Ótimo. Se eu for inspecionar a marcação dentro do navegador, vejo div id root, que é novamente nosso ponto de montagem para o aplicativo definido dentro do index.html, e então nosso aplicativo React é montado dentro do div, exatamente como você vê aqui. A marcação que definimos dentro do componente App, div e title. simples quanto isso. Agora, também temos o App.css aqui. Como você já percebeu, para criar alguns estilos ou estilizar um aplicativo React, basta criar um arquivo CSS. Escreva CSS normal aqui e importe-o dentro do componente. Simples assim. Nada de especial. Para atribuir classes aos elementos que temos dentro da marcação, precisamos passar o atributo className aos elementos, não à classe, mas ao className, porque lembre-se de que, embora seja uma marcação HTML, ela é traduzida para JavaScript nos bastidores. Isso significa que ele é processado pelo React. No React, em vez de passar apenas a classe, passamos o atributo className. Dentro do atributo className, especificamos quais nomes de classe esse elemento deve ter. Vamos passar algo aleatório. Vamos passar a classe de cartão que é definida dentro do CSS. Vamos apenas fazer o cartão e depois salvá-lo. Se inspecionarmos, você pode ver agora que esse div tem uma classe de cartão com o CSS definido aqui. Funciona exatamente assim. Não há nada de especial nisso. Então, vamos criar nossos próprios componentes. Dentro do código-fonte, vamos criar uma nova pasta chamada Componentes. Dentro dessa pasta de componentes, criaremos um novo arquivo, que chamaremos de Square.jsx. Aqui, vamos criar uma nova função chamada square e, por enquanto, ela retornará um div simples, olá. A partir desse arquivo, vamos exportar o quadrado padrão, assim mesmo. Agora, acabamos de criar um componente quadrado e queremos usá-lo dentro de outro componente. Na reação, você usa componentes dentro de outros componentes. Tudo é um componente do react. Voltamos ao aplicativo JSX, e aqui vamos importar quadrado dos componentes ao quadrado e, aqui dentro, vamos apenas digitar quadrado e fechar automaticamente. Você pode ver quando você quer usar componentes, você os usa como elementos HTML. No entanto, novamente, a primeira regra é que eles estão sempre em maiúsculas. Basicamente, os componentes são muito semelhantes às tags HTML reutilizáveis, mas são componentes com sua própria lógica definida internamente. Se acessarmos o aplicativo novamente, você verá que o olá está sendo adicionado aqui. Este é o nosso componente e a marcação dentro do quadrado é sobre olá. Se eu mudar para outra coisa, isso será refletido aqui. simples quanto isso. Agora, você sabe que qualquer atributo HTML pode receber alguns argumentos para passar algumas informações, para passar alguns dados para esse elemento. Por exemplo, temos tag de imagem. A tag de imagem espera dois atributos, source e alt, caso a imagem não seja carregada. Vamos prosseguir e tentar especificar esse vite.svg como a fonte dessa tag de imagem. Como o vite.svg é servido sob root, porque lembre-se daquela pasta pública mapeada para segmentos de URL, vou apenas especificar vite.svg, salvá-lo e você verá que funciona. Ele nos aponta para vite.svg, que está correto. Os componentes também têm atributos, mas todos esses atributos são totalmente definidos por nós dentro da definição do componente. Esses atributos são chamados de adereços. Assim como os elementos HTML têm atributos, os componentes têm solicitações para passar alguns dados dentro desse componente. Temos componente quadrado. Se abrirmos o componente quadrado, são apenas dados estáticos aqui , apenas mostram olá. E se eu quisesse exibir o componente quadrado e alterar o que será exibido no interior? Digamos que possamos duplicar componentes quadrados, assim mesmo, e teremos vários componentes quadrados, por exemplo, olá, olá, olá. Mas e se eles precisarem de algumas informações dinâmicas em tamanho, alguns dados dinâmicos como olá 1, olá 2, 3, 4, etc? Para fazer isso, precisamos passar adereços. Props é apenas o objeto que o componente recebe como primeiro argumento. Simples assim. Se quisermos cancelar os adereços de registro, abrirmos o console e se eu atualizarmos a página, você verá vários registros do console aqui. Por que temos vários? Porque executamos o componente quadrado várias vezes. Para cada componente, o registro do console é impresso. No momento, é um objeto vazio. Não é indefinido, é um objeto vazio. Tudo o que passarmos para o componente como um suporte, aparecerá abaixo do objeto props aqui. Assim como passamos atributos para elementos, passamos adereços para componentes. Digamos que, para este último componente quadrado, vamos passar o adereço. Novamente, será totalmente personalizado. Vamos chamar isso de valor. Vamos passar a Sequência 5. Voltamos aqui, eu atualizo a página, dentro do console do navegador, podemos ver o valor 5. Foi cancelado e bloqueado duas vezes. Bem, isso é errado, que foi cancelado duas vezes. Acho que o motivo pode ser o modo estrito aqui. Deixe-me tentar rapidamente e removê-lo. Se eu atualizar, agora tenho apenas um log do console. Isso é estranho. O problema é que, quando o componente é atualizado, ele é atualizado internamente. Quando o componente é atualizado, o JavaScript é executado novamente e a lógica interna do componente é executada novamente. Por alguma razão, o componente ósseo estrito força o componente a renderizar novamente o JavaScript dentro do componente para ser executado e vemos um registro do console do mesmo componente várias vezes. Vamos manter isso assim. Temos o valor 5. Para o resto dos componentes que temos aqui, ainda é um objeto vazio porque bem, não passamos nada dentro dele, mas para o último componente, passamos o valor 5, passamos o suporte. Ótimo. Acho que está claro que, como não passamos nada aqui, para esses componentes, é um objeto vazio, mas aqui passamos o valor 5. Agora, dentro do objeto props, temos o valor chave com a string de valor 5. Dentro da definição do componente quadrado, agora podemos usar esse valor aqui. Como é um objeto, ele está disponível em props.value. Vamos consolar explicitamente o log props.value e atualizar a página, vemos undefined e five, porque, novamente, para todos esses componentes que não passam value prop, valor será indefinido, mas para o último componente, o valor será a string 5. Ótimo. Agora, dentro da marcação JSX, podemos exibir expressões JavaScript. No momento, se eu digitar alguma coisa ou se eu quiser, vamos ver, exibir o valor desse adereço como um texto dentro do meu componente em vez de olá, para que pareça dinâmico. Eu provavelmente digitaria props.value. Mas isso vai funcionar? Vamos tentar ver. Se eu abrir minha página, vejo props.value como um texto porque não funciona. É só uma corda. Mas se quisermos avaliar props.value como um JavaScript dentro de nossa marcação JSX, precisamos usar colchetes. Simples assim. Dentro de colchetes, podemos inserir qualquer JavaScript válido e ele será avaliado e, eventualmente interpolado na marcação que escrevemos. Se voltarmos aqui, veremos apenas cinco. Mas onde estão os demais componentes? Se inspecionarmos a marcação, estará simplesmente vazia. Por estarem vazios, eles não ocupam nenhum espaço na página. Mas o último componente, que foi renderizado, tem cinco exibidos em seu interior. Exatamente o que passamos aqui como suporte? Se seguirmos em frente e passarmos outra sequência aqui, como olá, valor será meu nome. O valor será alguma coisa. Vamos remover este, salvá-lo e voltar. Você pode ver que tudo está sendo exibido assim que passamos. Dessa forma, usando adereços, podemos passar as informações para o componente. Aqui está uma dica rápida, pois sempre sabemos que o primeiro argumento para a função componente será o objeto props. Podemos usar a desestruturação em vez de escrever adereços... algo o tempo todo. O que vou fazer é aplicar a desestruturação diretamente nos argumentos da função. Como desestruturamos o valor da chave do objeto adereços, vou pegá-la assim. Agora parece muito mais limpo e não precisamos escrever adereços. algo. Dessa forma, podemos passar quantos adereços quisermos dentro do componente. Além disso [NOISE], podemos passar outro adereço especial predefinido chamado children. Crianças é algo que você passa dentro do componente como sua própria marcação. O que quero dizer com isso é que se você olhar dentro do componente quadrado agora. É fechado automaticamente. É e por dentro passamos diferentes adereços. No entanto, também podemos escrevê-lo assim. Quadrado e feche-o em uma linha separada. Então, lá dentro, podemos passar algo como div, olá. Talvez outro título diga, isso é título. Nesse caso, esse componente agora não é mais fechado automaticamente. Eles permanecem fechados automaticamente , mas é como um componente normal que não se fecha automaticamente e, por dentro, passamos a marcação. Tudo o que passamos dentro do componente dessa maneira. Essa marcação aqui, olá, esse é o título. Ele estará disponível dentro da definição do componente. Como adereço infantil, é um nome de chave reservado especificamente para isso. Se eu vou prosseguir aqui e registrar crianças no console. Se abrirmos o console novamente, você verá que, para o restante dos componentes em que não passamos filhos, ele é indefinido. Mas para o primeiro componente, se você abri-lo, há algumas coisas estranhas aqui. Esse é o JavaScript que está sendo realmente usado por trás da marcação JSX. Podemos pegar as crianças e renderizá-las. Podemos usá-lo como um slot. Em outras bibliotecas, é chamado de slots. No reator, é chamado de crianças. Você passa alguma marcação dentro do componente e , em seguida, o componente interno, usando-a quando criança, pode decidir onde exatamente ela será renderizada. Dentro dessa marcação, vou digitar, as crianças serão renderizadas abaixo. Dentro da div, vou interpolar crianças porque, novamente, se eu vou passar crianças assim, elas serão consideradas crianças em sequência. Mas como children é uma variável dentro dessa função, precisamos interpolá-la na marcação JSX. Simples assim. Agora, se olharmos dentro do nosso HTML, temos coisas diferentes aqui. Para o primeiro componente, temos algo, então temos filhos que serão renderizados abaixo. Então temos div, que são filhos que passamos para o componente dentro dele. Nós passamos olá lá e este é o título. Isso é exatamente o que vemos aqui. Esse HTTP do HTML é interpolado dentro do componente quadrado. Está disponível para crianças. Foi exposto como adereço infantil. Novamente, você não pode mudar. Sempre fica assim. É um adereço reservado para crianças. Nunca muda e sempre permanecerá assim , não importa o que aconteça. Para o resto de nossos componentes, nada será renderizado. Você verá que será uma div vazia. Sempre que você tenta exibir, ou digamos o que quer que seja, você tenta interpolar o nulo indefinido. Dentro da marcação JSX, ela não será renderizada porque, bem é considerada um valor vazio, não será exibida. Se eu for continuar e tentar exibir null por dentro, nada estará lá. Será apenas uma div vazia. O mesmo acontece com indefinido e falso. Todos os valores falsos não serão avaliados como algo. Eles serão simplesmente omitidos. Assim, podemos criar componentes. Legal, não é? No próximo vídeo, vamos criar um componente de placa. Vamos criar um componente de raiz quadrada e tentar incluir algumas funcionalidades no aplicativo. Te vejo lá. 44. 05 Como aplicar estilos de CSS: Olá. Vamos continuar criando o aplicativo. Na última vez, discutimos os componentes, como podemos criar componentes, como podemos transmitir crianças, quais são os componentes, como podemos exibi-los, etc. Agora, vamos começar e dar vida ao nosso aplicativo. O que vamos fazer agora é criar a marcação que será usada em nosso jogo. Voltamos ao aplicativo JSX. Vamos remover tudo daqui. Vamos remover esse nome de classe por enquanto, removeremos a importação do quadrado e criaremos um novo componente dentro da pasta de componentes, que chamaremos de JSX. Ele representará nosso conselho e colocaremos toda a lógica relevante dentro desse componente. Novamente, vou criar uma função de palavra. Por enquanto, vamos exibir div como olá e, a partir desse arquivo, vamos explorar esse componente da placa. Então, dentro do aplicativo JSX, vamos importar a placa da placa de componentes. Em seguida, vamos executá-lo aqui como um componente de fechamento automático. Agora voltamos ao navegador, vemos olá, que vem do componente da placa. Agora, dentro do quadro, vamos definir o marcador inicial. Vamos dar a ele um quadro de nomes de classe. Ainda não é tratado em nenhum lugar, nem em arquivo CSS, nem em qualquer lugar. Vamos apenas marcá-lo com o quadro de nomes da classe. Lá dentro, vamos criar linhas porque se você se lembrar de como nosso jogo vai ser um tic-tac-toe e tem que ser isso, digamos, uma estrutura semelhante a uma linha dentro do HTML. Vamos criar três linhas. Teremos três divs. Cada div terá um quadro de nomes de classe , uma linha e, dentro de cada linha, teremos três quadrados. Será basicamente apenas uma grade, três por três. Dentro de cada linha, vamos usar o componente quadrado. Vamos importar quadrado a quadrado. A propósito, isso./ representa a pasta atual onde esta placa de arquivo JSX neste caso, a localizou. Se eu digitar. /, representa essa pasta de componentes. Isso significa que tudo o que eu digitar mais adiante será resolvido nessa pasta. Eu importo default, export, este, um nome, seu quadrado interno, e tudo isso é importado desse arquivo quadrado aqui. Dentro de cada linha, vou correr o quadrado três vezes, sem mais nem menos. Eventualmente, parece algo assim. Se eu atualizar, ainda teremos a marcação do último vídeo, mas vamos removê-la e usar apenas o valor prop. Mas ainda precisamos passá-lo dentro de cada instância de raiz quadrada que executamos. Vou passar o valor zero aqui. O valor será um. A propósito, no último vídeo, eu passo o valor como uma string. Simples assim. Uma string pode ser passada sem colchetes, mas se você tentar passar cinco e quiser que seja um número em vez de uma string, você terá que usar colchetes. Novamente, colchetes em qualquer lugar da marcação JSX permitem que você use qualquer expressão JavaScript válida em seu interior. Zero como número é uma expressão JavaScript, e podemos passá-la como uma propriedade de valor, e será apenas o número 0 ou o número um. Se você quiser que seja uma string, basta digitá-la assim e será uma string. Uma expressão que é avaliada em string. Mas se for uma corda, você pode passá-la assim. Se passarmos números, teremos que usar colchetes. Valor 0, valor como esse. Deixe-me copiar tudo rapidamente e deixá-lo assim até as oito. Você pode ter uma pergunta por que começa do zero. Bem, eu não te disse, mas vamos abordar em breve como vamos representar o tabuleiro, como vamos administrar isso, e precisamos representar quadrados de alguma forma. Podemos representá-los por índices. Um aumento na programação começa do zero. Como vamos usar um aumento para gerenciar um jogo de tabuleiro, os índices começarão do zero. É por isso que, por enquanto, fornecemos índices aos nossos quadrados e eles começam do zero porque serão elementos da matriz. Voltamos aqui e vemos isso. Bem, se inspecionarmos o HTML, isso é exatamente o que escrevemos. Agora, vamos torná-lo um pouco mais estiloso. Voltamos ao quadrado JSX e nossos quadrados serão clicáveis. Em vez de div, podemos renderizar um botão com o tipo button e dar a ele um nome de classe de quadrado, que definiremos em um momento. Agora, parece que sim , e não é tão ruim, não é? Mas vamos aplicar nossos próprios estilos aqui. Se voltarmos a ser convidados aqui, exatamente nesta página, onde você pode ter todas as informações fornecidas, se você rolar aqui, temos styles.scss aqui. Bem, SCSS é para arquivos Sass. Sass é um pré-processador CSS que vamos usar. O que é um pré-processador CSS? É basicamente apenas uma linguagem construída sobre CSS e tem seu próprio conjunto de recursos. Eventualmente, quando escrevermos esse SCSS de pontos, ele será compilado em algo CSS de pontos e funcionará como um CSS normal. Mas tem a desvantagem de suas próprias características, por exemplo, como a nidificação. Em CSS normal, não temos permissão para aninhar seletores. Temos que escrevê-los em linha, como o rapper da história dos pontos, depois o espaço e depois a história dos pontos. No SASS, tudo pode ser aninhado. Podemos ter variáveis e coisas diferentes. Você pode procurar no Google por SASS, Syntactically Awesome Style Sheets. Você pode abri-lo, clicar em “Learn SASS” e acessar esta página muito rapidamente. Não é muito longo, é bem curto, abrange e mostra todos os recursos do SASS, por exemplo, variáveis. Ao usar o cifrão, você pode ter variáveis em CSS. Muito legal, e você pode se aninhar. Você pode ver se você escrever essa marcação SASS, ela se traduz nesse CSS, então vamos usar o SASS. Para fazer isso, precisamos instruir Vite. Precisamos dizer ao Vite que, em vez do CSS normal, também gostaríamos de usar o SASS, e o Vite tem suporte para SASS. Se voltarmos à documentação do Vite e clicarmos em “Pesquisar”, procurarmos SASS aqui e abrirmos o primeiro link, teremos a seção de pré-processador CSS, e o Vite fornece suporte integrado para arquivos SCSS. Então, para fazer isso, habilite o suporte necessário para instalar o compilador SASS. compilador SASS está disponível como pacote npm chamado SASS. Você pode ver esse comando aqui. Se eu digitar npm SASS, colocarei o primeiro link. Esse é o pacote que nos permite compilar o SASS em arquivos CSS. Então, só precisamos instalá-lo e, na verdade, a Vite cuidará do processo de transpilação. Eu só vou copiar esse comando, abrir o terminal, parar o comando pressionando Control C, então nosso servidor diff quebra, então eu vou instalar o SASS. Dash D é basicamente o mesmo que dash, dash save-dev. Só um atalho. Ele instalará o SASS como uma dependência do desenvolvedor e, se você examinar o pacote JSON agora, verá o SASS nas dependências do desenvolvedor. Ótimo. Agora, precisamos primeiro executar o npm run dev para iniciar o servidor novamente e podemos seguir em frente e realmente criar arquivos SASS. Dentro da pasta de origem, vou criar Styles.scss e o que vou fazer? Vou até o convidado e vou copiar tudo daqui e colocá-lo dentro do estilo CSS. Você não precisa entrar em muitos detalhes aqui. Essa é a marcação final que teremos em nosso aplicativo porque esses vídeos não são sobre CSS. Se você precisar mudar alguma coisa ou se quiser trazer algo novo aqui, você está livre para fazer isso. Por favor, mude, brinque com isso, vamos usar essa marcação. Dentro desses estilos, temos uma cláusula do conselho definida. Em seguida, dentro do tabuleiro, aninhamos a classe da linha do tabuleiro e, dentro da classe da linha do tabuleiro, aninhamos a classe quadrada. baixo do capô, se você abrir o SASS novamente, aninhamento compila esses seletores aqui, então basicamente a placa e a linha interna do tabuleiro serão compiladas para algo assim, e o quadrado será compilado para algo parecido. Isso é muito conveniente, eu acho. Temos classes de linha e raiz quadrada de tabuleiro e quadro, então o que vamos fazer é importar o arquivo SASS de pontos para nosso aplicativo. Não precisaremos mais do CSS do app dot, então simplesmente o excluímos. Em seguida, vamos para o componente do aplicativo e, em vez de importar o CSS do aplicativo, vamos importar estilos, pontos CSS, e isso funcionará. Agora temos classes de tabuleiro, linha de tabuleiro e quadrado aqui. Vamos para quadrado, atribuímos a classe quadrada, que será resolvida para esse CSS. Dentro do tabuleiro, temos um tabuleiro e uma fileira de tabuleiros, que serão resolvidos para essas classes. Agora, voltamos ao aplicativo e pronto, você pode ver, parece exatamente assim. No entanto, você pode ver que algo está errado ou algo está errado, na verdade é nossa marcação então precisamos alterá-la um pouco. Se acessarmos o aplicativo aqui, forneceremos o componente que envolve toda a nossa marcação. Vamos dar a ele a classe de aplicativo aqui que definimos exatamente assim. Assim, podemos dar a ele um nome de classe de App. O que ele fará é nos fornecer a caixa flexível básica com a configuração da coluna. Se voltarmos aqui, você pode ver que agora temos nossa grade final, que tem essa aparência. Muito legal. Isso é tudo sobre estilo. Agora você conhece mais um truque como você pode estilizar seu aplicativo usando o SASS. Se você já conhece algum outro pré-processador como o Less, você também pode ler na documentação do Vite como conectá-lo ou caneta. O SASS é bastante popular em todas as soluções comuns em aplicativos. Eu acho que é muito legal e muito conveniente. Agora, na verdade, começamos com interatividade, mas acabamos com estilos. Acho que, por enquanto, vamos acabar com estilos e, na verdade, no próximo vídeo, falaremos sobre interatividade. Acho que você não se importa. Como já trabalhamos muito aqui, introduzimos o SASS, criamos componentes quadrados e de placas e temos nossa bela marcação aqui, vamos realmente confirmar tudo. O que temos aqui? Removemos o CSS do aplicativo, modificamos o pacote JSON e excluímos alguns arquivos. Então, vamos adicionar tudo ao estado do palco. Vou digitar “Git add dot” para que tudo apareça sob alterações faseadas e vamos apenas confirmar tudo, e vamos nomear o commit como SASS instalado e criar componentes quadrados e de placa , básicos, algo assim. Mensagem de confirmação muito estranha, mas acho que funcionará. Nós comprometemos tudo. Para que tudo apareça no GitHub, precisamos implantá-lo porque, novamente, precisamos lembrar que, se você fizer alterações, elas permanecerão localmente no seu PC. Se você voltar para o GitHub agora, nada mudará porque todas as suas alterações ocorrem localmente, então você precisa implantar na hospedagem do GitHub toda vez que introduzir novas alterações localmente, então git push origin master. Eu faço isso e refresco, e agora temos tudo de bom. Incrível. Como prometi, o próximo vídeo será sobre interatividade, então nos vemos lá. 45. 06 Reagir o estado com o useState hook, reaja eventos: Olá de novo. Neste vídeo, conforme prometido, falaremos sobre interatividade. O que quero dizer com interatividade. interatividade é algo que acontece quando o usuário interage com a página da web. Quando eu clico no botão, algo deve acontecer. Um evento ocorre e algo é atualizado na tela. Isso se chama interatividade. Agora veríamos como podemos gerenciar isso no React. Em JavaScript bruto, em JavaScript simples sem nenhum React, você tem um arquivo JavaScript. Normalmente, você captura elementos com a API DOM, algo como documento obtém elemento por ID. Você pega um botão, depois escreve button.add event listener, e esse ouvinte, você anexa alguma função que será executada quando você clicar no botão. Mas, em reação, é praticamente o mesmo. Parece diferente, mas é quase o mesmo, então vamos abrir o JSX aqui. Só por exemplo, vamos criar um botão e vamos jogar com ele. Eu removi a placa por enquanto. Onde está o componente por enquanto? Não precisamos disso. Temos o editor eslint aqui, sem variáveis não utilizadas. Ele produz um erro em vez de premiar, vamos realmente colocá-lo em execução para que seja menos variável. No eslint, eu simplesmente não vou usar carros não utilizados e queria emitir um aviso, então agora ele será laranja em vez de vermelho e não nos incomodará muito. Então, eu vou criar um elemento de botão e vou chamá-lo, clique em mim, por favor. Agora, o que eu quero fazer nesse botão, talvez eu queira atualizar algo ou cancelar algo, registrar algo e ver algum valor no console do navegador. Como podemos fazer isso? Para cada elemento, para cada tag HTML usada dentro da marcação JSX, você pode passar um manipulador de eventos para que tenhamos eventos, evento clique, evento de mouse, diferentes tipos de eventos e sempre que digo manipulador de eventos, me refiro à função que será executada quando esse evento ocorrer. Por exemplo, vamos pegar esse elemento de botão. Se eu tentar passar atributo que começa com um a partir da inteligência, posso ver uma lista bem longa de eventos diferentes disponíveis para esse elemento. Onsubmit, onResize, onMouse, over onKeyUp, etc. momento, estamos interessados no evento onClick, então vou apenas fazer onClick e, para esse atributo no elemento do botão preciso passar um manipulador de eventos, uma função que será executada quando o clique ocorrer, então vou passar uma função vazia aqui e dentro dessa função, vou fazer console.log, “Olá”, então se eu salvar, eu volto para o aplicativo. Agora, sempre que eu clicar no botão, você verá olá ser impresso toda vez que eu clico nele para que ele realmente funcione. Em JavaScript simples, todos os manipuladores de eventos sempre recebem o objeto de evento como o primeiro argumento, portanto, essa função aqui em JavaScript simples sempre recebe um objeto de evento que representa o evento. Vamos tentar cancelar o registro desse objeto aqui. Vamos ver se há alguma diferença. Então, se eu clicar no botão aqui, posso ver olá e depois vejo o objeto de evento, então esse objeto de evento é um invólucro em torno do objeto de evento nativo que você normalmente obteria com JavaScript simples, mas em react, isso é algo chamado evento sintático, então é basicamente apenas um invólucro em torno do evento nativo com poucas propriedades de reação. Se você inspecioná-lo, você tem uma pilha de propriedades diferentes aqui, bem como um evento nativo que pode ser acessado apenas com o evento event.native. Dessa forma, se você precisar, você pode obter um objeto de evento JavaScript nativo. Mas, na maioria das vezes , tem apenas o suficiente para se referir a um evento sintético. Na maioria das vezes, ele contém as informações que você está procurando, caso precise usá-las , portanto, nesse caso, não precisamos de nenhum objeto de evento. Estamos interessados em fornecer alguma interatividade ao aplicativo, então agora vamos experimentá-lo e ver como podemos fazer isso. Digamos que temos um contador. Deixe-me seguir em frente e criar uma variável. Vamos chamá-lo de “Let counter, que começa com um”. Agora, o que eu quero fazer é exibir esse contador aqui e sempre que clico no botão, gostaria de aumentar o valor de um, 2, 3, etc. Dentro do manipulador de eventos OnClick, na verdade, vamos tentar mover essa função aqui para o aplicativo para que fique mais bonita. Parece mais atraente e fácil ler, então podemos criar essa função aqui e chamá-la onBtnClick e eu vou copiá-la daqui, colá-la aqui e, para o atributo onClick, vou passar btnClick. Assim, digamos que dentro desse manipulador de eventos, eu gostaria de aumentar o contador aqui, então, em vez do log do console, talvez vamos mantê-lo. Vamos dizer que contador é igual a contador mais um. Nada de especial. Agora, podemos ver que ele realmente foi aumentado? Vamos para frente e para baixo. Vamos exibir o valor do contador , então vou usar colchetes para interpelar novamente o valor em apenas seis porque ele tem um contador variável. Eu o guardo. Eu volto aqui, vejo um. Só que nós temos isso inicialmente, ótimo. Se eu tentar clicar nele, nada acontece. Mas por que isso? O problema com essa abordagem é que o React não segue exatamente as mesmas regras do JavaScript simples. Então, se você estivesse usando JavaScript simples e tentasse escrever uma lógica muito semelhante, teria funcionado, mas não com o React. No React, sempre que você precisar um valor que mude ao longo de algum período de tempo, depois de, digamos, que durante o período de interatividade apenas desvalorizou as mudanças, você precisa torná-lo um estado. Portanto, no React, um valor que muda deve ser um estado. Em apenas um segundo, agora podemos criar nosso primeiro estado. Mas antes de fazermos isso, deixe-me explicar rapidamente por que isso não funciona. Vou abrir o Paint e escrever rapidamente como o React lida com isso. No React, existe o conceito de re-renderização. Uma nova renderização ocorre basicamente quando o componente está sendo repintado na página da web. Quando usamos state, state sempre aciona um componente para renderizar novamente, e o estado na próxima renderização será atualizado. Mas, se criarmos variáveis como essa e tentarmos atualizá-las, isso não fará nada. A razão para isso é porque quando tentamos mutar a variável desse jeito, isso não acionará a renderização do componente novamente. O ciclo de vida de um componente é , na verdade, baseado em novas renderizações. Quando atualizamos a página, o componente está sendo montado na página. Isso significa que está sendo renderizado pela primeira vez. Então, digamos que esse quadrado aqui represente uma única renderização. O componente está montado na página, foi renderizado e exibido. Agora, pelas regras do React, se eu quiser atualizar algo na tela, se eu quiser atualizar algo dentro desse componente, preciso acionar uma nova renderização para isso. Aproximadamente nesta foto , ficará assim. Essa nova renderização se traduzirá em uma nova renderização diferente. Esses são quadros e comutadores do React sobre eles. Então esta é nossa primeira renderização. Digamos que atualizemos o estado. Novamente, o estado será o valor que muda ao longo de algum período de tempo. O estado foi atualizado, atualização de estado aciona uma nova renderização e agora temos um componente que foi renderizado novamente. Novamente, com variáveis, se vamos usá-las desse jeito, não funcionará. O motivo dessa atualização de variável é que essa linha número 9 não aciona uma nova renderização e isso é um problema. Permanecemos neste primeiro quadro e tentamos atualizar esse contador mais um aqui, e isso não faz nada, não aciona uma nova renderização, que significa que precisamos usar estado para todos os valores que sabemos que serão alterados ao longo de algum período de tempo após alguma interatividade. Cada renderização aqui, então esta é a primeira renderização, a segunda renderização, elas oscilam uma da outra, elas não sabem nada uma sobre a outra. A primeira renderização não sabe que haverá uma segunda renderização e, assim como a segunda não sabe se houve uma primeira renderização ou uma renderização anterior, elas oscilam uma com a outra. Tudo isso é gerenciado internamente pelo React, mas o ponto principal aqui é que precisamos saber que, para atualizar algo, precisamos acionar um componente para renderizar novamente. Sempre que um estado é atualizado, ele aciona a renderização de um componente novamente. Agora, se quiséssemos que esse contador fosse atualizado e funcionasse conforme o esperado, a partir do React, precisaríamos explorar algo chamado useState. No topo, vou apenas importar useState e aqui estou usando a importação nomeada do React. O que é useState? No React, existe um conceito de React Hooks. O que é um gancho? Hook é basicamente apenas uma função que nos permite manipular o ciclo de vida do componente. O que é o ciclo de vida do componente? O ciclo de vida de um componente é apenas um período de tempo em que algo está acontecendo dentro do componente. Ele está sendo montado, atualizado, está sendo desmontado, então esse é o ciclo de vida do componente. Podemos usar o React Hooks para manipular de alguma forma o ciclo de vida desse componente. Portanto, useState nos permite criar um valor que será alterado ao longo do ciclo de vida de um componente. Como podemos usá-lo. Dentro do nosso componente, precisamos apenas chamar useState como uma função. Novamente, todos os React Hooks são funções. A propósito, todos os React Hooks sempre começam com o prefixo de uso. Portanto, essa é a convenção no React. Sempre que você vê algo usado, é definitivamente um React Hook. Chamamos isso de função e, como primeiro argumento, precisamos passar o estado inicial. Qual será o valor padrão para esse estado? No nosso caso, queríamos dar a ele um valor inicial de um, então vamos passar apenas um. Agora, essa função useState sempre retorna uma matriz. useState sempre retorna uma matriz de exatamente dois elementos. Vamos seguir em frente e chamá-lo de valor de retorno por enquanto, e vamos tentar registrá-lo no console, escrever diretamente dentro do componente. Vamos ver o que temos aqui? Então, eu atualizo a página e aqui eu tenho, como eu disse, uma matriz de exatamente dois elementos. O primeiro elemento será valor do estado neste momento na renderização atual, e o segundo valor dentro dessa matriz será a função de atualização que precisamos chamar para atualizar esse estado. Deixe-me mostrar o que quero dizer. Na maioria das vezes, você verá que vamos usar uma reestruturação porque sabemos que useState sempre retorna uma matriz de exatamente dois elementos, para que possamos aplicar uma reestruturação com segurança. O primeiro elemento será nosso estado e o segundo, uma função que precisamos chamar para atualizar o estado. Eles são chamados de estado e função de atualização de estado, e podemos chamá-los como quisermos. Nosso estado será chamado de counter, e a função de atualização para definir o estado será chamada de setCounter. Agora vou remover esse contador de esquerda igual 1 um. Vou remover esse contador de linha mais 1, nós realmente não precisamos dele. Vamos tentar consolar nosso contador. Na verdade, não precisávamos cancelar o registro, já o temos aqui. Se eu salvar, atualizo a página, ainda temos uma aqui. Esse é o nosso estado inicial. Agora, se quisermos atualizar o estado, precisamos chamar a função de atualização de estado, setCounter. Entre o clique e o clique, queremos aumentar o valor. Então, o que podemos fazer. Podemos chamar setCounter e, internamente, só precisamos passar um novo valor para esse estado. Por enquanto, vamos colocar um valor estático. Digamos que 10. Eu salvo, volto para o navegador, agora clico no botão e você vê que o valor foi alterado para 10. Dentro do console importa que você veja olá aqui. aconteceu é que quando você clica no botão, setCounter foi chamado, ele atualizou o estado de um para 10. Em seguida, sua renderização ocorreu novamente. Se voltarmos a esse pequeno diagrama aqui, o que aconteceu é que esse componente foi renderizado na página. Clicamos no botão, atualizamos o estado e essa atualização de estado acionou a nova renderização. O segundo quadro aqui representa nossa renderização atual, onde o estado atual é 10. Por que vemos o registro do console aqui? Na verdade, vemos o log do console aqui porque o temos dentro de OnBtnClick. Mas e se colocarmos o log do console aqui fora do OnBtnClick. Vamos tentar novamente. Eu atualizo a página. Primeiro, vemos dois registros do console, mas bem, isso é esperado porque, como você se lembra, eu disse no vídeo anterior sobre o React StrictMode, era intencional que ele renderizasse isso é esperado porque, como você se lembra, eu disse no vídeo anterior sobre o React StrictMode, era intencional que ele o componente duas vezes para detectar erros, mas esse não é o ponto, ou talvez esse seja o ponto. Deixe-me remover o React StrictMode por um segundo. Eu atualizo a página. vemos um registro do console Olá, vemos um registro do console porque o componente é montado, a lógica interna do componente é executada, vemos o log do console. Ótimo. Mas agora, se eu clicar no botão, vemos que o valor é atualizado, o componente é renderizado e vemos olá pela segunda vez. Vemos isso porque, novamente, em cada nova renderização, a lógica dentro do componente está sendo executada novamente. Javascript é executado novamente quando o componente é renderizado novamente, então o estado é persistido porque o useState é um recurso interno do React. Bem, ele é totalmente gerenciado no React, então o valor que muda ao longo do período é gerenciado pelo React. É persistido. Tudo é legal. Mas vemos o registro do console aqui porque, bem, isso é algo que trazemos para o componente e a lógica é executada novamente, então é por isso que a vemos pela segunda vez. Se estivermos prestes a atualizar o estado novamente na próxima vez que o componente for renderizado novamente, você verá outro olá, etc. Você verá olá toda vez que o componente for renderizado novamente. Mas o que acontece se eu clicar no botão novamente? Veja, eu clico mais uma vez e não vemos mais nenhum olá. O React é inteligente o suficiente para detectar que o estado permanece o mesmo, então o valor permanece o mesmo. O React é inteligente o suficiente para não atualizar o componente o tempo todo novamente, novamente. Ele não executa recálculos o tempo todo se o valor do estado for o mesmo. Vamos prosseguir e tentar aumentar o contador. Podemos fazer o contador mais 1, desse jeito. Agora, se eu atualizar a página, clico no botão, vejo 2, vejo olá, porque novamente o componente é renderizado novamente. Eu clico no botão novamente, e agora o olá, vemos 3 e assim por diante e assim por diante. No entanto, nessa abordagem de atualização de estado dessa forma, quando precisamos definir um novo valor para esse estado e queremos calcular o novo valor do estado a partir do valor do estado atual, precisamos usar uma abordagem ligeiramente diferente. Em vez de fazer um contador mais 1, podemos realmente passar retorno de chamada alternativo para a função de atualização de estado. função de atualização de estado pode receber um dos dois argumentos. Ou um novo valor de estado, como você viu, então 5, 10, novo valor que definirá o cenário, ou podemos passar o retorno de chamada para essa função de atualização de estado e, dentro desse retorno de chamada, primeiro argumento será value, que representa o estado atual. Digamos que contador de corrente. Tudo o que retornarmos desse retorno de chamada será definido como o novo valor. A partir desse retorno de chamada, agora podemos retornar contador atual mais 1. Será o mesmo e, do ponto de vista do usuário, nada será alterado, mas internamente, essa é a abordagem correta quando você precisa calcular o novo valor do estado a partir do valor do estado atual ou anterior. Como esse é o contador e gostaríamos de aumentá-lo, precisamos saber o estado atual do contador. Sempre que você tiver essa situação, sempre use a abordagem de retorno de chamada. Se quiséssemos apenas configurá-lo como um número aleatório, não precisamos dele porque não precisamos do estado atual para calcular o novo estado. Voltamos ao aplicativo. Eu refresco. Novamente, como eu disse, do ponto de vista do usuário, nada mudou. Com algo assim, você pode manipular elementos na página. Com base nesse conhecimento básico simples e básico, conhecimento básico simples e básico, todos os aplicativos React estão sendo construídos desse jeito. Você tem vários estados. Você pode criar quantos estados quiser. Você pode manipulá-los como quiser com diferentes eventos no evento de clique, mouse, quando algo é aberto, algo é fechado, tudo é gerenciado com estados como esse. Acho que para este vídeo, isso será suficiente. Agora você conhece os eventos do React que podem ser transmitidos. Para esse atributo, você pode passar qualquer manipulador de eventos para executar alguma função quando algum evento ocorrer. Esse manipulador de eventos sempre recebe um objeto de evento como primeiro argumento, caso você precise dele. Se você não, bem, simplesmente não o use. Se você precisar atualizar algum valor na página, no contador de cores, no texto, seja o que for, temos um estado para isso. As variáveis não funcionarão porque o React não funciona dessa maneira. React é baseado no conceito de rerenderização e, para manter o valor nas renderizações, precisamos usar o estado. Podemos fazer isso usando o use state hook. ganchos no React são apenas funções que você chama durante o ciclo de vida do componente para manipular dados dentro do componente. Algo parecido. No próximo vídeo, veremos como podemos usar esse conhecimento e como podemos aplicá-lo em nosso jogo. Vamos criar o estado do jogo e manipular quadrados para que, quando clicarmos neles, isso de alguma forma atualize o estado. Nos vemos lá. 46. 07 Criando estado de tabuleiro de jogo: Oi. No último vídeo, falamos sobre interatividade, sobre estado, o que é estado, como isso pode nos ajudar. Neste vídeo, podemos continuar com o estado, mas desta vez vamos aplicá-lo em nosso jogo. Do vídeo anterior , algumas coisas mudaram aqui. Vou referenciar essas mudanças muito rapidamente e tenho a configuração do eslintrc desatualizada. Não coloquei nenhum papel de vars não utilizado como aviso. Na verdade, vamos adicionar outro commit para isso. premiação de bares reduz o aquecimento. Ok, isso vai funcionar muito bem. Agora, vamos continuar com a interatividade. Então, se formos para o tabuleiro, aqui, criaremos nosso estado de tabuleiro, que basicamente representará nosso tabuleiro de jogo. Mas a questão é: como vamos fazer isso? Se você se lembra, uma vez mencionei que será uma matriz. É por isso que temos nove elementos aqui e todos eles começam com zero. Eles simplesmente começam com zero, nem todos. Então, eu vou abrir a tinta aqui. Eu vou te dizer exatamente como podemos representar o estado do jogo com uma matriz. Será uma matriz de nove elementos. Então, por padrão, será uma matriz vazia com nove elementos. E por padrão, cada elemento será nulo, ok. Então, por padrão, inicialmente teremos uma matriz de nove elementos, cada elemento será nulo. Então, quando vamos clicar em um quadrado. Portanto, nossos quadrados serão representados por índices dentro dessa matriz. O primeiro quadrado terá índice zero, segundo quadrado terá índice um, dois e assim por diante. Quando clicamos em um quadrado, digamos que clicamos no quadrado com índice um, ele mudará seu valor de nulo para x ou zero com base em quem clicou naquele quadrado. E desse jeito, vamos administrar o estado. Então, eventualmente, teremos uma matriz de nove elementos, cada elemento pode ser nulo se o quadrado não for clicado, ou x, ou zero se o quadrado foi clicado. Vamos prosseguir e, internamente, primeiro importaremos useState do react. Dentro do quadro, vamos criar um novo estado, que podemos chamar de quadrados. Defina quadrados, será useState. Agora, inicialmente, precisamos criar uma matriz de nove elementos e cada elemento por padrão será nulo. Para isso, podemos usar apenas JavaScript simples aqui, então não podemos chamar um construtor de matriz com nove como comprimento de matriz. Em seguida, chamaremos o método de preenchimento de pontos e preencheremos a matriz com nulos. Eventualmente, ele produzirá uma matriz de nove elementos em que cada elemento é nulo. Agora, como podemos realmente associar cada quadrado a cada componente que representa um quadrado? Neste momento, passamos por 0,1,2,3 e 4. Então, em vez disso, vamos passar quadrados zero. Portanto, como o quadrado é nosso estado, sempre será uma matriz que pegou o primeiro elemento dessa matriz. Então, para o segundo quadrado, podemos pegar o segundo elemento e assim por diante. Precisamos fazer isso para cada quadrado. Vamos seguir em frente e fazer isso para cada quadrado. Então, nós o salvamos. Voltamos ao aplicativo. Este site não pode ser acessado. Isso porque eu não conheci o servidor de desenvolvimento. Então, npm run dev. Eu volto aqui e agora podemos ver que nossos quadrados estão vazios. Bem, isso é esperado porque temos valor nulo. Nós aprovamos valores nulos. E se você se lembrar, se tentarmos exibir null, ele não será avaliado. Isso resultará em nada e em HTML. Agora, o que podemos realmente fazer? Você pode ver que precisamos atualizar o estado de alguma forma, atualizar quadrados, atualizar o estado quando clicamos em um quadrado, como podemos fazer isso? Portanto, permanecemos informados, mas temos toda a lógica sobre o componente quadrado dentro do componente quadrado. O que podemos fazer é usar adereços. Assim, podemos definir alguma função aqui dentro da placa que gerenciará a lógica, e podemos passar essa função como um suporte para o componente quadrado. Então, novamente, nós apenas passamos alguns dados, algumas informações para os componentes. Então, aqui, o que vamos fazer? Vamos criar uma nova função chamada handle square click. Essa função receberá um argumento. Vamos chamar essa função com uma posição de argumento. Será o 0,1,2,3,4,5,6,7 e 8 será o índice do quadrado. E dentro dessa função, faremos alguma coisa. Por enquanto, vamos apenas mantê-lo vazio. Então, como eu disse, vamos usar prompts para passar dados para o quadrado. O que queremos fazer quando clicamos nesse quadrado, esse clique quadrado da alça ficará frio. Então, o que podemos fazer? Podemos passar OnClick ou Squared Click , qualquer que seja o nome que você deu a esse adereço. Vamos chamá-lo apenas de OnClick. E para esse adereço OnClick, vamos passar e construir um clique quadrado. Mas o problema é que, como passamos essa alça ao quadrado, clique aqui, e se a passarmos dessa maneira, pegaremos esse OnClick aqui dentro do quadrado, e precisaremos chamar essa função de quadrado dentro de quadrado e passar a posição como argumento porque manipula quadrados clique recebe argumento de posição. Então, quando chamamos essa função, precisamos passar essa posição. Mas o problema é que o quadrado realmente não precisa saber nada sobre isso. O que queremos fazer idealmente, queremos apenas pegar a função onClick aqui e, para o atributo onClick, queremos passar essa função dessa forma. E a Square não fará nenhuma lógica sobre isso. Tudo será gerenciado aqui a bordo. Então, para fazer isso, o que podemos fazer com a propriedade onClick aqui, podemos passar uma função, e essa função chamará handleSquareClick com a posição que precisamos. Então, eventualmente, parece algo assim. Podemos até simplificar isso e remover o corpo funcional. Agora parece mais conciso e parece assim. Por que precisamos passar uma função que chama outra função? Por que podemos chamá-lo assim? Bem, o problema é que, como você se lembra, quando os componentes são montados na página, o JavaScript dentro do componente é executado e, com essa sintaxe, alguns JavaScript são usados linha por linha, e assim que o JavaScript usa luz, ele verá que chamamos essa função aqui nessa linha. Então, o que ele fará é chamar essa função de escrever imediatamente. E qualquer que seja a disfunção que retornaremos , receberá o valor da propriedade onClick aqui, já que nossa função não retorna nada, ela será indefinida e, eventualmente, onClick here inside square será indefinida. Nada vai acontecer. Teremos essa função chamada write straightaway e undefined no final. Isso não é exatamente o que queremos. Em primeiro lugar, o manipulador de eventos é uma função em primeiro lugar. É por isso que passamos uma função, não outra coisa. Então, passamos uma função que chama manipuladores rapidamente com os argumentos de que precisamos. Bem, como você pode ver, precisamos fazer isso para cada quadrado aqui, assim mesmo e passar posição diferente, mas você pode notar que há uma pequena repetição aqui. Temos muitas coisas que podemos simplificar aqui. Então, em vez de enquadrar valores, quadrados, depois índice de matriz, depois onClick e repetir alças clicadas o tempo todo, podemos simplificar essa função. Podemos simplificar essa sintaxe usando outra função. Então, o que podemos fazer aqui para evitar essa repetição? Aqui dentro do quadro, podemos criar outra função que podemos chamar de algo como um quadrado de renderização. Esse RenderSquare recebe novamente posição que será a posição que será um índice quadrado e, dentro dessa função, podemos então retornar a marcação JSX. Vamos apenas copiar aqui. A partir de RenderSquare, agora podemos retornar quadrado, então, em vez de quadrados zero, vamos passar a posição dos quadrados e handleSquareClick . Em vez de zero, vamos passar a posição. Eventualmente, algo assim. Agora, dentro do JSX, usamos colchetes para interpolar o JavaScript nele. Como podemos interpolar variáveis aqui, que são expressões JavaScript exatamente da mesma maneira, podemos chamar funções aqui porque as funções também fazem parte das expressões JavaScript. Em vez de escrever quadrados todos eles desse jeito, o que podemos fazer é simplesmente abrir colchetes, chamar RenderSquare e passar índice zero para dentro. Assim que o componente saltar, essa função será chamada com zero como argumento, que será a posição dentro dela. Ele retorna a marcação JSX e essa marcação JSX será interpolada no local onde essa função foi bem chamada, basicamente aqui. Exatamente o mesmo que faremos com o resto dos nossos quadrados. Eu só vou copiá-lo duas vezes. Eu removo isso porque não precisávamos mais dele e farei exatamente o mesmo com o resto dos nossos quadrados, então 3, 4, 5, 6, 7, 8. Agora, novamente, chamamos a função quando o componente é montado, essa função retorna a marcação JSX e essa marcação JSX será inserida no local em que essa função é chamada. Se você acabou de referenciar essa função dessa forma, nada acontecerá. Se eu voltar, vamos ver o que acontece. Bem, vemos algumas coisas estranhas aqui e se tentarmos ver, temos apenas dois quadrados aqui. O que estamos fazendo agora basicamente tentar exibir a função em si. Não é o que a função retorna , mas a boa assinatura da função e reação não funciona dessa forma. Se você tentar exibir os objetos como estão, não conseguirá fazer isso. Primeiro você precisa convertê-las em cadeias de caracteres, mas não é isso que vamos fazer agora. Isso é um pouco avançado e voltaremos a isso no futuro. Chamamos essa função, passamos um argumento e verificamos se tudo funciona. Basicamente, refatoramos levemente nosso componente, mas ele faz exatamente o mesmo. Ele renderiza o valor no índice que especificamos aqui, valor da nossa matriz de quadrados, que é o estado. Dentro do handleSquareClick, precisamos fazer alguma lógica aqui, então alguma lógica para exibir quadrados de alguma forma. Para atualizar o estado do quadrado, precisamos chamar a função de atualização de estado em nosso caso ao indexar seus quadrados. Isso é exatamente o que vamos fazer. Como nosso estado é uma matriz que será alterada ao longo do período de tempo e nosso novo estado de matriz que calcularemos precisa ser calculado a partir do estado atual, usaremos a versão de retorno de chamada do estado definido. Vou passar o retorno de chamada aqui e o primeiro argumento será o estado quadrado neste momento. Vou chamá-lo de CurrentSquares e precisamos de alguma forma manipular estado CurrentSquares e obter novo estado de quadrados com valores atualizados. Um ponto aqui que eu não mencionei no vídeo anterior é que não podemos alterar a variável de estado. O que quero dizer com isso? Se usarmos useState e tentarmos pegar esses quadrados e tentarmos fazer algo assim, quadrados em alguma posição são iguais a algo. O que fazemos aqui é manipular diretamente esse estado em vez de usar essa função de atualização de estado, isso não funcionará. Isso é proibido desta forma, estado não será atualizado. No React, ele não funciona dessa maneira. Precisamos chamar a função de atualização de estado o tempo todo para fazer isso, então, novamente, isso não funcionará. Chamamos setSquares e, dentro de Setsquares, também temos currentSquares, que representa o estado de cada vez. Se tentarmos alterar novamente o estado diretamente aqui, isso não funcionará. Isso simplesmente não funcionará. Não é assim que o React funciona. Precisamos chamar a função e retornar um novo valor. O React não se trata de alterar valores diretamente. O React trata de retornar novos valores, se isso fizer sentido para você. A partir do setSquares, precisamos retornar um novo valor. O que podemos fazer para percorrer todos os nossos quadrados e, de alguma forma, atualizá-los, podemos usar o método Array.map e o método Array.map não altera o estado, mas retorna um novo valor de matriz. É por isso que é seguro fazer isso. Um retorno currentSquares.map, então vamos percorrer nosso estado quadrado. Nosso primeiro argumento será o valor que analisamos no momento, então será nosso SquareValue. Então temos o índice do quadrado. Vamos chamar isso de just pos. Como já temos uma posição nesse escopo de função, se tentarmos chamá-la de posição, teremos colisão de variáveis. Nós apenas continuamos fazendo as pazes. Sempre que eu retornasse do.map para o elemento atual, ele associará um novo valor para esse elemento. Aqui, a lógica será bem simples. A posição que passamos para essa função é a posição na qual basicamente clicamos. Para não nos confundir, vamos renomeá-la para a posição clicada e aqui, indexar dentro de Array.map, vamos chamar posição. Vamos dizer se a posição clicada é igual à posição do quadrado que examinamos Nesse caso, retornaremos X por enquanto a partir do.map. Caso contrário, se o quadrado que será repetido no momento não for o quadrado em que clicamos, simplesmente retornaremos o mesmo valor quadrado. Agora vamos salvá-lo, parece que, quando formatado pode ser um pouco confuso porque temos uma função que chama a função e, dentro da função, temos um retorno de chamada, basta se acostumar com isso, então voltamos ao aplicativo. Agora vamos tentar clicar em um quadrado. Eu clico no meio e boom, nada acontece. Por que isso? Vamos tentar no console registrar o estado quadrado aqui. Vamos ver o que temos. Temos uma matriz de taxa de nulos e, se eu clicar, nada realmente acontece. Vamos ver o que pode estar errado aqui. A parte errada aqui é que você pode ver o componente quadrado não foi salvo. Isso porque, bem, tudo o que acabei de escrever aqui não foi salvo, então as alterações basicamente não foram confirmadas. Eu o salvei e agora deve funcionar. Eu clico no quadrado e você vê agora que eu tenho X aqui e se você vê aqui, o estado foi atualizado. Agora, como cliquei no quadrado com índice 4, 0, 1, 2, 3, 4, clicamos nesse quadrado e dentro dessa matriz atualizamos o elemento no índice 5 e definimos seu valor como X, e definimos seu valor que tem exatamente o que precisamos. Se clicarmos em todos esses quadrados, você verá que todos os quadrados serão preenchidos com acesso, que é exatamente o que queríamos, e vemos todos esses registros do console novamente o tempo todo. Porque, como atualizamos esse estado, componente renderiza novamente a lógica interna e vemos o log do console toda vez que a lógica é executada novamente. Ótimo. Algo assim, somos capazes de administrar nosso estado. Por enquanto, acho que isso será suficiente. No próximo vídeo, apresentaremos nossos jogadores. Na verdade, teremos o jogador atual, então poderemos diferenciar quem clicará nesse quadrado a seguir. Será X ou zero, então agora você pode ver que temos apenas X, o que não é exatamente o que estou procurando. No próximo vídeo, vamos abordar isso. Quando clicarmos nesse quadrado, ele será X ou zero. Te vejo lá. 47. 08 Adicione jogadores X e o: Olá. No vídeo anterior falamos sobre esses quadrados de estado e, na verdade, conseguimos colocar X dentro do quadrado quando clicamos nele. Neste vídeo, vamos adicionar mais funcionalidades, então, quando clicamos no quadrado, podemos realmente exibir x ou zero. Em outros termos, teremos um jogador. Antes de introduzirmos novas mudanças, muitas mudanças foram feitas até agora em relação ao vídeo anterior. Adicionamos essa funcionalidade quando clicamos no quadrado, exibimos X dentro deles. Bem, vamos prosseguir e realizar essas mudanças. Vou apenas digitar git add. e vou chamar essa mensagem de confirmação chamada, digamos, exibir X ao clicar em um quadrado. Vamos iniciar o servidor novamente. Incrível. Agora, vamos adicionar basicamente uma funcionalidade de player. O player é algo que mudará ao longo do ciclo do componente. Isso significa que vai ser um estado. O que vamos introduzir é um novo estado, e o estado será o jogador. No entanto, não faremos nenhuma complicação sobre isso. Será apenas um valor booleano simples, que nos dirá quem será o próximo jogador. Vamos chamá-lo de algo como IsxNext. Se for verdade, definimos o estado como x, caso contrário, será zero, simples assim. Internamente, podemos criar um novo estado e renomeá-lo como isXNext, e as funções de atualização definem isxNext e, por padrão, ele será falso. Como já temos praticamente tudo o que precisamos, vamos modificar essa linha 12. Aqui, retornamos x. Está codificado aqui. Mas, em vez disso, vamos apenas introduzir outra condição simples, se não for o caso. Nós vamos perguntar. Se for xNext, o valor que associaremos ao quadrado clicado será X, caso contrário, será zero. Logo após atualizarmos o estado de setSquare, também atualizaremos o setISXNext, vamos alterná-lo, pois é um booleano. Vou chamar setISXNext e, como precisamos ativá-la e ela ordenará que ela seja ativada, precisamos saber a alternância booleana atual, precisamos saber a alternância booleana atual, que neste momento é verdadeira ou falsa, e simplesmente a inverteremos. Novamente, vamos usar a versão de callback do set state updater. Vamos pressionar o callback. CurrentIsXNext ou vamos simplificar. Vamos chamá-lo como P ou prev para o anterior, ou vamos sem complicações, seja qual for o currentIsXNext. Para alternar esse booleano, só precisamos aplicar negação na frente, sem mais nem menos, e pronto. O que ele fará, ele assumirá o estágio booleano atual. Será verdadeiro ou falso, se for falso, aplicamos negação ao falso, ela se tornará verdadeira e, se for verdade, aplicamos negação, ela se tornará falsa. Basicamente, inverta o booleano e fazemos isso depois de atualizarmos o estado dos quadrados definidos. Fazemos isso, voltamos ao nosso aplicativo. Clicamos e agora temos zero primeiro. Agora clicamos mais, temos o X e vamos direto, e você pode ver que ele está alternado e invertido, e tudo funciona conforme o esperado. No entanto, se eu clicar no quadrado novamente, você poderá ver algo jogado aqui. O problema é que, quando clicamos no quadrado, a lógica é executada novamente e ela atualiza o quadrado no índice na posição em que clicamos. O que queremos acrescentar aqui, outra condição. Se o quadrado já tem valor, se não for nulo, simplesmente não executamos essa lógica. Aqui estão as alças internas superiores, clique no quadrado, podemos perguntar se os quadrados ainda, clickedPosition, o valor é verdadeiro. Valor verdadeiro significa não nulo. Nosso valor quadrado pode ser nulo, X ou zero. Se esse valor for verdadeiro, significa que não é nulo. Nesse caso, simplesmente retornamos dessa função. A palavra-chave return sai da função e não vai além. Nós o salvamos. Vamos ver, o nosso vai parecer. Eu clico em quadrados e tento clicar no quadrado novamente e nada acontece porque, novamente, ele verifica a condição e sai da função. Muito legal. Algo assim, adicionamos um jogador ao nosso jogo. Nosso próximo passo será exibir a mensagem na parte superior, quem será o próximo jogador. No entanto, vamos fazer isso no próximo vídeo. Por enquanto, vamos comprometer nossas mudanças atuais. Vou nomear esse commit. O que fizemos, vamos revisar. Basicamente, apresentamos um jogador aqui. Introduziu o jogo a um jogador. Ao clicar em um quadrado, mostre x ou zero. Nós nos comprometemos com isso, implantamos. Eu escrevi errado. Push Origin Master. Só fiz isso porque fiz algo nos bastidores quando desligo o vídeo. Desculpe-me, você não deveria ter isso. Vou usar a primeira bandeira desse jeito, e agora tudo está no GitHub. Por favor, não se importe com essa parte, você não a terá. Ótimo. Nos vemos no próximo vídeo. 48. 09 Mostrar mensagens do próximo jogador e do vencedor: Oi. No vídeo anterior, conseguimos adicionar a funcionalidade do jogador ao nosso jogo. Neste vídeo, continuaremos e exibiremos a mensagem aqui no topo da grade, que diz: o próximo jogador é e se tivermos um vencedor, mostraremos o vencedor. Neste vídeo, abordaremos tudo isso mais o cálculo do vencedor. Em primeiro lugar, o que queremos fazer? Precisamos decidir o que exatamente queremos colocar na marcação da mensagem. O próximo jogador é x ou zero. Bem, queremos fazer isso dentro do App jsx. Aqui, apenas uma simples tag H2 que diz que o próximo jogador é, por enquanto, alguém. Se eu voltar, fica assim por enquanto. No entanto, já temos um problema. O que precisamos usar aqui para mostrar quem será o próximo jogador. Como você pode ver, toda lógica e estado residem dentro do componente da placa. Isso significa que não está disponível para o mundo exterior. O único componente que conhece quadrados, todo o estado e toda essa lógica é o próprio componente da placa e você pode passar os dados necessários desse componente para seus componentes secundários. Por exemplo, como fazemos com o quadrado. Se quisermos ter acesso a esse estado ou dados fora da diretoria, isso é impossível. Temos duas opções aqui. A primeira opção é realmente mover a mensagem do próximo jogador dentro do componente do tabuleiro. Talvez o coloque aqui. Temos todos os dados de que precisamos no escopo desta mensagem para que possamos realmente obter algo dela e, eventualmente, exibi-la. Temos o próximo jogador, esta ou a segunda opção é mover parte dessa lógica para o componente principal. Por exemplo, para o componente do aplicativo e, em seguida, passe as informações necessárias para o componente da placa por meio adereços e, em seguida, pause outra informação necessária para enviar uma mensagem aqui. Se tentarmos visualizá-la, se abrirmos a tinta, teremos uma imagem como essa. Temos um componente de aplicativo que renderiza componente da placa e, dentro do aplicativo, renderizamos a mensagem. Por enquanto, ele não faz parte do aplicativo, mas ainda faz parte do aplicativo, não faz parte da placa. O estado é gerenciado aqui dentro do componente da placa. Como a mensagem não faz parte do quadro, ela não tem relação com ela. Ela vive como uma folha separada, então isso significa que é impossível ter acesso ao que está acontecendo dentro do navio. A primeira opção que mencionei é tornar a mensagem parte do componente do quadro aqui. Se formos a bordo e colocarmos uma mensagem aqui, poderemos acessar os dados, que possamos gerenciá-los aqui. Essa é a primeira opção, mas não vamos fazer isso, queremos que a mensagem faça parte do componente do aplicativo. segunda opção é elevar a lógica, elevar o estado para o componente pai, que é app, e depois passar os dados necessários para os componentes correspondentes usando adereços. A lógica ficará dentro do aplicativo e, em seguida, passamos os dados para a placa por meio de adereços e seguida, passamos outros dados para a mensagem, novamente usando adereços no futuro. Por enquanto, não é um componente, mas a ideia é a mesma. Compartilhamos dados no componente de patentes. Abrimos o quadro e, a partir do quadro, vamos pegar o estado e movê-lo para o componente do aplicativo. O mesmo que faremos com a importação. Vamos colocá-lo dentro do aplicativo e também lidar com o clique quadrado. A partir de agora, ele estará ativo e será gerenciado dentro do componente do aplicativo. Eu copio isso aqui. Eu o coloquei dentro do aplicativo. Simples assim. Nós salvamos o tabuleiro, mas você pode ver que, dentro do tabuleiro, não temos mais alça de clique quadrado. Se passarmos o mouse, a raiz quadrada do identificador não está definida porque nunca foi criada em nenhum lugar aqui, o mesmo acontece com quadrados. componente da placa agora tem esses valores indefinidos. Bem, isso significa que precisamos ter acesso a ele de alguma forma e faremos isso por meio de adereços. Como agora temos quadrados e manipulamos o quadrado, clique aqui dentro do aplicativo, podemos passá-los para o componente da placa com adereços. Vou passar quadrados aqui desse jeito e lidar com o clique quadrado exatamente da mesma maneira. Agora, dentro do tabuleiro, posso aplicar o link de destruição pegar quadrados e manipular o clique quadrado. Agora, se eu salvar os dois arquivos, abro meu aplicativo novamente. Tudo funciona como antes, mas agora o estado vive dentro do aplicativo e todos os dados necessários são passados aos componentes da placa por meio de adereços. Ótimo. Isso significa que agora a mensagem que exibimos no componente do aplicativo tem acesso ao estado. Podemos exibir a mensagem. Nossa lógica será bem simples. Vou criar uma nova variável aqui e vou te dizer o porquê. Chamamos isso de mensagem ou, digamos, mensagem de status. Aqui vamos fazer isXNext, retornamos x string, caso contrário, retornaremos zero string e mensagem de status, já que ela estiver disponível, nós a interpolaremos em JavaScript. Vamos dizer que o próximo jogador é {Mensagem de status}, ou digamos que, em vez de mensagem de status, vamos chamá-lo de próximo jogador. O próximo jogador é o próximo jogador. Nós o salvamos e temos próximo jogador zero. Incrível. Nós clicamos. Na verdade, era zero, e você vê que mudou e continua e tudo funciona conforme o esperado. No entanto, você pode ter uma pergunta: por que exibimos como uma variável aqui? Por que não criamos oito estados para isso, talvez? O fato é que esse próximo jogador é algo chamado estado derivado ou computado, e por que não criamos outro estado para isso usando o estado de uso? estado derivado ou computado é o valor derivado do estado mais recente. Como temos isXNext como um estado e sabemos que toda vez que o componente é executado, a lógica interna é executada, o que significa que essa linha de código será novamente em cada renderização de cada componente. O problema é que quando o componente é renderizado novamente, o estado é atualizado. Isso significa que, para a renderização atual, o estado que temos aqui estará atualizado. É o estado mais recente que temos. Como essa lógica é executada novamente, ela sempre usará o estado mais recente aqui isXNext. É por isso que realmente não precisamos criar outro estado para isso. Acabamos de criar um valor derivado do último valor do estado. Bem, pode parecer um pouco complicado, mas se você pensar bem, não há nada de sofisticado nisso. Já temos algum valor que muda e, na verdade, derivamos algo desse valor. Nada mais do que isso. É por isso que não precisamos criar outro estado de uso, não faz nenhum sentido fazer isso. Agora temos a mensagem que diz quem será o próximo jogador, mas vamos mais longe e mostrar o vencedor. Sempre que temos um vencedor, gostaríamos de mostrar. O vencedor é esse cara, o próximo jogador X. Se voltarmos para o convidado que foi compartilhado com você no início, e se você procurar por calculatewinner.js, você tem uma função aqui, calcule o vencedor. Vamos copiar essa função. Vamos voltar ao nosso aplicativo e, dentro do código-fonte, vamos criar um novo arquivo e chamá-lo de winner.js. Se você notou, não nomeamos esse arquivo com a extensão dot.js6 porque esse arquivo não tem nenhuma marcação js6. É apenas um JavaScript normal. partir daqui, do arquivo js, vamos exportar a função calculatewinner. O que ele faz, pega nossa matriz de quadrados, que, novamente, se você se lembrar, é uma matriz em que armazenamos nossos valores quadrados; nulo, X ou zeros, e a partir dessa matriz, calcula o vencedor. Se não houver vencedor para quadrados de algodão, ele retornará nulo. Se houver um vencedor, ele retornará X ou zero, o que ocorre na linha 15. Como isso funciona? Como a função funciona? Aqui temos uma matriz de linhas definida, que basicamente representa todas as combinações vencedoras possíveis no jogo tic-tac-toe. Por exemplo, 0, um e 2 é a combinação 0, 1 e 2, portanto, se você tiver X em uma linha. Você pode verificar todas as combinações possíveis que você vê aqui. Novamente, é apenas um conjunto de todas as combinações vencedoras possíveis. Então, o que fazemos aqui é usar o simple for-loop. E nós os examinamos. Examinamos cada combinação vencedora. Estou dizendo que é muito simples. Comparamos nossa matriz atual de quadrados com a combinação vencedora. Se tivermos essa combinação vencedora em nosso estado de quadrados e nossa matriz de quadrados, então apenas retornaremos o vencedor. Aqui usamos a desestruturação da matriz na linha 13. As linhas na posição dos olhos representam essa matriz. partir dessa matriz, empacotamos o primeiro, segundo e terceiro elementos e os chamamos , b c. Por exemplo, para essa matriz , a será zero , b será um, dois será c. Então, usando essa lógica if, vemos se há algum vencedor. Se você está realmente interessado em saber como isso funciona, tente realmente colocar os valores nessa fórmula, digamos, você mesmo. Um pouco de lógica aqui. Voltamos ao aplicativo e podemos fazer isso simplesmente executando essa função dentro do componente do aplicativo. Como precisamos passar pelo estado quadrado e calcular, o vencedor produzirá como vencedor. Não precisamos criar outro estado. Essa variável vencedora que temos será, novamente, o estado derivado do estado quadrado. Eu vou seguir em frente aqui, talvez ainda por cima, eu vou criar a variável vencedora. O que vou fazer é importar o calculatewinner. Isso se chama export, então eu o importo com colchetes do vencedor. Eu chamo essa função aqui e por dentro eu passo nosso estado quadrado. Eu terei um vencedor aqui. Vamos tentar fazer o registro e ver o que temos. Eu abro o console. Dentro do console, eu tenho nulo porque, bem, não temos nenhum vencedor. Quando eu jogo, nulo, nulo. Vamos criar um vencedor. Se eu clicar aqui agora, terei a combinação vencedora, e você verá que ela produz zero aqui, porque agora, bem, temos um vencedor, que é zero. Nesse caso, precisamos exibir. Vamos em frente. Já temos o próximo jogador, é o próximo jogador, mas vamos modificar um pouco essa mensagem. Ou talvez não a toquemos. Aqui, vamos criar outra variável que chamaremos de mensagem de status neste momento. Aqui, vamos perguntar se temos vencedor, então vamos dizer, vencedor é vencedor, a variável que temos. No entanto, precisamos usar o modelo de string aqui para aplicar a interpolação de strings. Vou transformar essa string em um modelo de string substituindo aspas singulares regulares por marcas invertidas. Isso me permitirá usar a interpolação usando o cifrão e os colchetes, então o vencedor é o vencedor. Caso contrário, se não tivermos nenhum vencedor, usaremos a próxima mensagem de jogador que já temos aqui. Em vez de mostrar que o próximo jogador é o próximo jogador, desta vez vamos mostrar apenas a mensagem de status. Eu escrevi errado. Será uma mensagem de status. Agora, vamos ver o que temos aqui? Então, temos apenas o próximo jogador, o próximo jogador. Eu entendo. Em vez disso, precisamos dizer que o próximo jogador é o próximo jogador. Se voltarmos, o próximo jogador é zero. Vamos jogar o jogo. Vamos criar um vencedor. Agora vemos a mensagem: o vencedor é X. Ótimo porque temos um vencedor. Legal. No entanto, aqui está um problema. Se você tentar jogar o jogo, se continuar, ainda podemos clicar em quadrados, mas isso pode ser facilmente corrigido. Já temos a lógica para sair da função se clicarmos no mesmo quadrado duas ou três vezes apenas várias vezes. Aqui, vamos apenas estender essa condição e contaremos. Se clicarmos no mesmo quadrado duas vezes ou se tivermos o vencedor, sairemos da função. Tão simples quanto isso. Vamos tentar. Eu joguei o jogo. Nós temos o vencedor agora. Se eu clicar em qualquer um dos quadrados, não executarei nenhuma lógica porque saímos daqui porque isso produz talvez falso, talvez verdadeiro, não importa, mas aqui definitivamente é verdadeiro. Temos a condição de saída. Simples assim, estamos quase terminando nosso jogo. A única funcionalidade que adicionaremos aqui será o histórico do jogo. Poderemos navegar pela história do jogo. Vamos acompanhar nossos movimentos que fizemos e poderemos viajar entre eles, mas vamos gerenciar isso no próximo vídeo. Por enquanto, essas mudanças são suficientes. Na verdade, vamos colocá-los no Git porque apresentaremos muitas coisas diferentes aqui. Vou abrir o terminal, adicionar tudo ao palco e nomear todas essas mudanças como, vamos ver, vamos ver, uma visão geral. Primeiro, retiramos o estado do conselho. Ele apareceu dentro do componente do aplicativo e depois exibimos o vencedor. Bem, isso é muito. Vamos contar, elevar o estado para o componente do aplicativo e mostrar a mensagem de status para o usuário. Sem mensagem de status para o usuário, calcule o vencedor. Não vamos complicar com as mensagens. Acho que isso será suficiente. Eventualmente, implante tudo no GitHub. Nessa nota profunda, vamos adicionar este vídeo. Te vejo na próxima. 49. 10 Mostrando o desenho do jogo: Olá. Neste vídeo, continuaremos falando sobre, na verdade, as mensagens que exibimos para o usuário aqui. O único ponto que perdemos no vídeo anterior, em que exibimos a mensagem de status, é o sorteio do jogo. E se terminarmos o jogo, mas eventualmente não tivermos nenhum vencedor? Nesse caso, gostaríamos mostrar outra mensagem ao usuário dizendo que, digamos, x e zero empatados, então há um empate. Para fazer isso, precisamos aplicar mais lógica aqui. Mas vamos fazer isso dentro um componente que vamos criar especificamente para a mensagem de status. Dentro dos componentes, vou criar um novo arquivo, que chamarei de mensagem de status. Esse será o novo componente. A partir daqui, vou criar um componente de mensagem de status de exportação. Mensagem de status. Assim por enquanto, será um div, que diz olá. Além disso, preciso exportá-lo daqui. Então, dentro do App JSX, vou importar quadrados de componentes quadrados. Opa, desculpe-me, não uma mensagem de status quadrada. Então, aqui, em vez da mensagem de status H2, vamos exibir o componente da mensagem de status assim. Então, removemos isso. Agora, a mensagem de status deve estar em algum lugar dentro do componente da mensagem de status. No entanto, não temos nenhum dado aqui, é por isso que novamente usaremos adereços para passar todos os dados necessários para o componente de mensagem de status. Temos a próxima camada e mensagem de status aqui, que a moverá diretamente para o componente de mensagem de status. Não temos ISXNext e não temos nenhum vencedor aqui. É por isso que esperamos que o vencedor seja aprovado e o ISXNext seja aprovado. O cálculo do vencedor é feito aqui. No entanto, o fato é que também precisamos detectar quando não temos quadrados vazios e não temos um vencedor? Precisamos escrever essa lógica. Para exibir o sorteio, precisamos saber se todos os quadrados estão ocupados com alguma coisa e ainda não temos um vencedor, para obter esse valor, aquele booleano que indica que precisamos acessar nosso estado de quadrados novamente. precisaremos dele na mensagem de status. Vamos passá-lo aqui também. Teremos o vencedor, ISXNext e os quadrados ficarão aqui. Passe tudo como adereços. Então, aqui, quando eu renderizo um componente de mensagem de status , vou passar o vencedor , vou passar isxNext e vou passar quadrados. Ótimo. Agora, aqui vamos usar algo chamado renderização condicional. Bem, na verdade você não sabe disso, mas já aplicamos renderização condicional aqui na linha 3-5. renderização condicional é simplesmente exibir algo com base na condição. Por exemplo, aqui, se eu abrir colchetes dentro do JSX e escrever, digamos, uma condição simples, cinco é menor que 10. Nesse caso, exiba div, que diz cinco a menos que 10. Caso contrário, exiba outro div que diga outra coisa. O que você vê aqui é chamado de renderização condicional. É basicamente isso que fazemos aqui. Em vez de simplesmente usar strings aqui, podemos escrever uma marcação JSX, assim mesmo, e tudo eventualmente ficará assim. Mas não precisamos de marcação JSX, precisamos de cadeias de caracteres simples, então mantemos isso assim. Agora, que tal desenhar? Qual é a lógica para exibir o sorteio? Precisamos saber que temos todos os quadrados ocupados no grid e não temos vencedor. Para obter o booleano que indica se não temos quadrados livres no quadro, criaremos outra variável porque, novamente, será um estado derivado. Vamos dizer que não há mais movimentos. Serão quadrados. Cada método é o método que pode ser chamado de apagar. Ele retornará verdadeiro ou falso. Nós repassamos a chamada para todos. Esse retorno de chamada é executado para cada elemento dentro da matriz de quadrados. Se cada retorno de chamada, se para cada elemento o retorno de chamada retornar verdadeiro, então, eventualmente, o valor final será verdadeiro. Se pelo menos um retorno de chamada retornar false, o valor final será falso. Esse é basicamente o nome de cada. O callback tem exatamente os mesmos argumentos do método map. Primeiro, temos o elemento que será o valor quadrado no nosso caso. Isso é suficiente, não precisamos de índice e não precisamos da matriz em si. Simplesmente verificamos se o valor quadrado não é igual a nulo. Nós verificamos isso. Se todo valor não for igual a nulo, toda a condição retornará verdadeira. Se pelo menos uma raiz quadrada não for nula, toda a estrutura, toda a condição, retornará false. Isso é exatamente o que estamos procurando. Agora, simplesmente vamos e temos o div, e podemos aplicar várias condições aqui. Se tivermos um vencedor , poderemos mostrar algo. Aqui está o truque: como também podemos aplicar a renderização condicional. Se tivermos um vencedor, podemos usar uma extremidade lógica e, em seguida, podemos exibir qualquer JSX que quisermos. Isso também é renderização condicional e é uma alternativa para escrever isso. Se tivermos um vencedor, mostre isso, caso contrário , exiba nulo. Se você se lembrar, nulo será avaliado como nada e eventualmente, nada será exibido, mas pode ser entediante escrever isso todas as vezes, é por isso que as pessoas geralmente escolhem essa maneira de escrever as coisas. Mas você precisa ter cuidado. Essa coisa aqui, quando você verifica a condição, deve ser um valor booleano. Se não for um valor booleano , mas for algo verdadeiro, por exemplo, como zero, ele exibirá zero. Zero é considerado um valor falso, mas não é um booleano. Portanto, a forma como o operador and funciona, somente quando essa condição retorna exatamente falsa. Precisamos ter certeza de que esse valor seja booleano se você quiser usar essa abordagem com um fim lógico. No nosso caso, o vencedor já é um booleano, então não precisamos fazer isso. No futuro, você definitivamente se deparará com essa situação, quando se lembrar disso, especialmente quando for lidar com uma corrida e dados provenientes de APIs. Nossa lógica é ser a seguinte. Se tivermos um vencedor, queremos mostrar o vencedor como vencedor. Vou apenas copiá-lo e colocá-lo aqui. Então, podemos aplicar outra renderização condicional aqui e dizer que, se não tivermos um vencedor e não tivermos nenhum movimento , podemos exibir outra coisa. Se eu salvá-lo, ele será formatado automaticamente. Vamos acabar com uma estrutura como essa. Então, teremos outra condição quando não tivermos um vencedor e não tivermos nenhum nodo se movendo para a esquerda. Mas essa coisa não parece feia, mas pode ser muito impraticável e às vezes muito difícil de ler. Em vez de fazer isso, podemos escrevê-lo de uma forma mais legível. Então, se você se lembra do que fizemos no componente da placa, criamos a função quadrada do renderizador a partir da qual retornamos a marcação JSX. Aqui, podemos aplicar exatamente a mesma abordagem e escrever as condições para renderização condicional dentro dessa função. Aqui vamos contar. Algo como renderiza uma mensagem de status, ok? Essa função não aceitará nada como argumento porque, bem, não lidamos com nenhum argumento aqui. Temos acesso a todos os dados que temos no escopo superior. Aqui, vamos apenas perguntar. Se tivermos um vencedor dessa função, retornaremos vencedor é vencedor. Então vamos perguntar se não temos vencedor e não temos mais jogadas, isso significa que temos um empate, nesse caso, exibimos zero e x de altura. Caso contrário, tecnicamente, podemos adicionar outra condição, como se não tivéssemos um vencedor e não tivéssemos mais movimentos nesse caso, os jogos continuam e mostramos próximo jogador é o próximo jogador, desse jeito. No entanto, podemos torná-la como uma declaração de retorno padrão dessa função, porque não faz nenhum sentido aplicá-la se, porque esta é a última e definitivamente, ela será acionada somente quando essas duas falharem, então não precisamos realmente verificá-la aqui ou podemos fazer isso, vamos continuar assim, vamos verificar essa condição e em No final se não tivermos nenhuma condição que nos satisfaça, nesse caso não retornaremos nada caso algo dê errado para nós. No entanto, isso nunca acontecerá. Vamos embrulhá-lo em div. O próximo jogador será o próximo jogador, não precisamos de nenhum cifrão, na verdade não precisamos mais de nada disso, temos apenas uma mensagem de status de renderização e, temos apenas uma mensagem de status de renderização e em vez de toda essa construção estranha, podemos simplesmente chamar a função de mensagem de status de renderização. Agora, parece muito mais legível, não é? Voltamos ao nosso jogo e vemos que o próximo jogador é, o que é correto, vamos criar um vencedor e tudo funciona conforme esperado, mas vamos mais longe e na verdade, não temos nenhum vencedor aqui, bem, isso é difícil. Isso não é difícil, então, como você pode ver agora, todos os quadrados estão ocupados com alguma coisa, mas você não tem nenhum vencedor e, eventualmente, temos zero e x empatados, exatamente o que estávamos fazendo, o que é ótimo. Agora, vamos estilizar isso porque você pode ver que temos esses arquivos de estilos aqui desde o início, mas não fizemos muito sobre isso porque estávamos ocupados com toda essa funcionalidade, então vamos seguir em frente e estilizar essa mensagem de status porque já temos nossos estilos aqui. Se olharmos de perto a história, lidaremos com isso no futuro Temos a classe de mensagem de status definida aqui, incrível, então vamos para a mensagem de status aqui e para esse elemento de encapsulamento para div. Vamos adicionar uma mensagem de status do nome da classe, se salvarmos, já temos essa, temos margem, talvez vamos transformá-la em elemento H2, como era antes, mas na verdade nada realmente mudará porque temos o tamanho da fonte, que está definido aqui, ótimo. Agora vamos adicionar algo aqui porque, como você pode ver, os elementos de extensão que aparecem como uma mensagem de status também têm um peso de fonte normal, provavelmente eu pretendia que fosse essa tag H2. Também temos classes aqui, texto verde e textos laranja, que podemos aplicar aos nossos jogadores x e zero, então o que eu vou fazer é fazer assim, então, para esses zero e x que temos aqui, podemos envolvê-los em elementos de extensão como esse, e a esse elemento de extensão, podemos realmente adicionar vantagens. X vai ser verde e zero vai ser laranja, então adicionamos as tags verdes para x, para zero vamos adicionar mais o nome do texto laranja, agora parece assim, muito legal. Em seguida, o que precisamos fazer é, de alguma forma, condicionalmente, quando tivermos o próximo jogador, aplicar estilos condicionalmente. Bem, isso é algo novo sobre o qual ainda não falamos, então precisamos de alguma forma aplicar condicionalmente as classes. Novamente, vamos agrupar o próximo jogador em espaço e exibir o próximo jogador aqui, mas agora também precisamos aplicar classes dinamicamente com base no player, então, para abranger, vamos passar o nome da classe e, em vez de apenas passar a string, vamos passar a expressão JavaScript, então, novamente, vamos usar colchetes e aqui estamos vou perguntar. Se for o Xnext, neste caso, aplicaremos a classe verde de textos , caso contrário, aplicaremos a classe laranja de texto, então, como é um JavaScript, você pode usar qualquer método disponível para alguma forma transformar, aplicar, combinar, concatenar a string e, eventualmente, ela será avaliada como a string do nome da classe aqui, então vamos ver. próxima camada é zero e, na verdade, é laranja e, à medida que jogamos, você pode ver as mudanças de cor e as cores funcionarem, que funciona de forma incrível. Então, no final, também temos o vencedor como vencedor, então, a mesma lógica aqui, vamos aplicar ao vencedor. O vencedor é o vencedor, mas aqui desta vez vamos perguntar se o vencedor igual a x, só então usamos as tags verde, caso contrário, texto, laranja vamos verificar rapidamente, ótimo, o vencedor é x. Talvez uma coisa que possamos adicionar aqui e que possa ser útil para o futuro e para nós agora é que você pode ver agora sempre quisermos exibir algo, é sempre envolto em um elemento, neste caso na tag H2, em div, mas e se eu quiser não descartar, não exibir nenhum div aqui? E se eu quiser apenas exibir o vencedor é, como acontece com a tag span, sem agrupá-la em uma div, porque se você abrir a marcação, ela é encapsulada na div, se eu não quiser fazer isso? Eu só quero mostrar que o vencedor é e span sem qualquer div, como diretamente dentro de H2. Nesse caso, podemos usar algo chamado fragmentos do React, então o fragmento do React é basicamente apenas um elemento vazio, então se eu remover o div e digitar React.fragment, importar o React do react porque agora usamos namespace React é basicamente um componente, mas é como um componente vazio, apenas um espaço reservado. Se eu vou usar o fragmento React em todos os lugares aqui, eu atualizo a página, jogo, abro a marcação, aqui você vê que nada renderizado, exceto que o vencedor é, desculpe-me, exceto que o próximo jogador está no espaço, eu não tinha nenhum elemento de embalagem. Novamente, o fragmento do React representa basicamente um elemento vazio, mas o fragmento do React é uma sintaxe muito ampla e é bom saber que você sempre pode usá-lo, no entanto, o fragmento do React tem uma sintaxe mais leve. Se você removê-lo e manter seus colchetes vazios, desse jeito, esta é uma versão curta do fragmento do React. Podemos remover o namespace React daqui e remover fragmentos do React em todos os lugares, e apenas manter colchetes vazios assim e funcionará, então isso também é um fragmento de reação, mas essa é uma sintaxe curta sem dizer explicitamente React.fragment, sinta-se à vontade para usar qualquer um, eu prefiro usar essa sintaxe, menos código, melhor. Agora, terminamos definitivamente com as mensagens de status, então vamos confirmar nossas mensagens, desculpe-me, confirme nossas alterações porque bem, fizemos muita coisa, falamos sobre renderização condicional, falamos sobre estilos condicionais, estilos dinâmicos, nomes dinâmicos de classes e também exibimos a mensagem de desenho, ótimo. Agora, eu já adicionei tudo ao estado do stitch, desta vez vamos usar a interface de usuário do VSCode, então eu clico no sinal de “mais” aqui para organizar todas as alterações, agora elas estão todas em estágio e podemos digitar uma mensagem aqui e pressionar commit, mas eu prefiro selecionar tudo manualmente, mas quero que seja preparado e seguida, digitar manualmente git commit e determine. A mensagem de confirmação será essa jogada ou, sim, exibir mensagem de desenho, aplicar estilos ou componente de mensagem de status e pronto. No próximo vídeo, começaremos com a história do jogo, falaremos sobre como podemos realmente introduzir esse recurso da história do jogo que podemos percorrer Isso vai ser divertido. Nos vemos lá. 50. 11 Implementando histórico de jogos: Olá. Neste vídeo, falaremos sobre a história dos jogos. No último vídeo, falamos sobre o game draw para exibir as mensagens que aparecem aqui na parte superior. próximo jogador é: temos um vencedor, temos um empate, o que é incrível, mas desta vez vamos falar sobre história dos jogos para podermos clicar em qualquer jogada que fizemos e depois percorrer a história. Para conseguir isso, precisamos realmente transformar nosso estado. Da forma como gerenciamos atualmente um estado de jogo, fazemos isso usando quadrados e estados isxNext. Tudo bem e continuaremos gerenciando isso dessa maneira. No entanto, mudaremos um pouco sua forma. Como a história é algo que precisamos lembrar porque seremos capazes de atravessá-la, precisamos transformá-la de alguma forma em uma matriz. Deixe-me abrir o Paint e mostrar exatamente como vamos representar o estado dos jogos. Por ser uma história, será uma série de elementos. Será uma matriz e dentro dessa matriz, cada elemento será um objeto. Será basicamente uma matriz de objetos e cada objeto nessa matriz terá duas chaves, quadrados e isXNext. Cada objeto nessa matriz representará o estado do tabuleiro de jogo no momento de nossa mudança. Para acompanhar os movimentos que fazemos no jogo, nosso CurrentMove, precisamos de um contador. Precisamos de alguma forma rastrear qual é o nosso CurrentMove para que possamos viajar nessa história. Se clicarmos em um item do histórico, digamos que vá para o Movimento Número 1, na verdade iremos para o Movimento Número 1 e nosso CurrentMove será alterado. Para isso, precisamos de outro estado para rastrear isso. Vamos ver como isso vai parecer na realidade. Aqui na parte superior do aplicativo, vou criar um novo estado, que chamaremos de histórico e setHistory, e isso precisa ser uma matriz. Por padrão, já temos um estado de jogo vazio, assim como temos aqui nas linhas 11 e 12. Vamos criar uma matriz vazia com um objeto dentro e, por padrão, serão quadrados, que serão uma matriz de nove elementos preenchidos com nulos, e então isxNext será falso, assim como temos aqui. Podemos remover isso com segurança. Em seguida, criaremos outro estado que representará nosso CurrentMove. Vamos em frente. Criamos currentMove e setCurrentMove. Por padrão, nosso CurrentMove será zero. Nosso contador será baseado em zero. Ótimo. Agora podemos ver que, como mudamos tudo, temos muitos erros aqui. Vamos mudar isso. Como podemos obter estado mais recente do tabuleiro de jogo que temos aqui? Podemos criar outra variável que será nosso valor derivado dos estados history e currentMove. Podemos chamá-lo, digamos, de GamingBoard. Isso vai ser história e nosso CurrentMove. Na verdade, ele nos dará esse objeto para nosso CurrentMove. Agora, em vez de analisar apenas quadrados aqui, vamos passar Gamingboard.squares. Você pode ver que eu até tenho o IntelliSense para isso. Incrível. Agora, handleSquareClick, vamos tocar nisso em um segundo. Vamos para a mensagem de status aqui. No momento, analisamos dois adereços, isXNext e squares. Agora tudo está combinado em um único objeto. Podemos simplesmente passar o objeto para a mensagem de status. O que vou fazer é analisar GamingBoard diretamente para a mensagem de status. Vou remover esses dois adereços. Vou abrir a mensagem de status aqui. Agora, como eu analiso o GamingBoard, em vez de desestruturar o isXNext e os quadrados, farei o GamingBoard. Vou desestruturar o GamingBoard aqui. Agora, preciso digitar GamingBoard.squares, GamingBoard.isxNext, e aqui também, GamingBoard.isxNext. Mas, em vez disso, o que farei, já GamingBoard é apenas um objeto com duas chaves, quadrados e isxNext, vou aplicar outra desestruturação aqui. O que vou fazer com o objeto GamingBoard desestruturar quadrados e isXNext. Um lembrete rápido. Isso é o mesmo. Essa única linha nos substitui sempre por escrever GamingBoard.squares assim GamingBoard.squares assim e GamingBoard.isxNext. Incrível. Lidamos com a mensagem de status. Vamos lidar com todo o resto. Para embarcar, analisamos quadrados. Agora temos GamingBoard.squares e agora, de alguma forma, precisamos lidar com HandleSquareClick. Bem, a lógica é que temos história e sempre que criamos uma nova jogada, sempre que jogamos, precisamos ampliar nossa matriz. Precisamos adicionar novos valores a essa matriz. Dentro do HandleSquareClick, vamos fazer isso. Primeiro, agora temos GamingBoard.squares aqui. Então, em vez de definir quadrados, vamos fazer setHistory e voltaremos a essa lógica em um segundo. Em vez de setisXNext, o que vamos fazer? Vamos apenas incrementar nosso CurrentMove. Sempre que clicarmos em um quadrado, o movimento, o contador será incrementado. Por isso, se você se lembra nosso exemplo de vídeos anteriores sobre contador, esse é exatamente o caso. CurrentMove, e podemos chamá-lo de currentMove inside. No entanto, já temos esse nome aqui como nosso estado, então vamos simplesmente chamá-lo de move. O movimento será movimento mais 1. Vamos apenas incrementá-lo novamente. Move representará nosso estado atual para CurrentMove. Dentro do SetHistory, em vez de currentSquares, vamos chamá-lo de CurrentHistory, e agora precisamos estender o histórico de alguma forma. Em primeiro lugar, precisamos conhecer nosso estado de jogo mais recente. Para fazer isso, precisamos pegar o elemento mais recente da matriz do histórico. Podemos fazer isso digitando. Talvez digamos que a variável lastGamingState será história, e vamos pegar o último elemento fazendo history.length menos 1. Dessa maneira, podemos pegar elemento mais recente da matriz histórica, que novamente será um objeto dessa forma. Agora, o que podemos fazer é calcular um novo estado que vamos adicionar à matriz do histórico. Já temos a lógica aqui. Em vez de retornar, vamos colocá-lo em uma nova variável chamada nextGamingState. Em vez de currentSquares, vamos usar LastGamingState.squares e, em vez de isXNext, vamos fazer LastGamingState.isxNext. Agora, para definir o novo valor para o estado do histórico, precisamos retornar desse retorno de chamada. A partir desse retorno de chamada, o que vamos fazer, vamos concatenar o que acabamos de criar aqui, NextGamingState, com nosso estado histórico atual. Podemos usar o método array.concat para isso. CurrentHistory.concat e vamos apresentar um novo objeto aqui. Precisamos analisar um objeto dessa forma. Squares será o NextGamingState. Nós o chamamos de NextGamingState, vamos chamá-lo de NextSquaresState. Vamos analisá-lo assim. IsXNext será, novamente, o inverso de um booleano, como fizemos antes, mas desta vez vamos nos referir ao nosso LatestGamingState que temos aqui, então LatestGamingState.isxNext. Vamos aplicar a negação para inverter o booleano e agora tudo funcionará magicamente. Vamos voltar aqui e experimentar o histórico de registros do console e o CurrentMove, ambos, para ver o que realmente está acontecendo. Vamos ao histórico de registros do console e ao CurrentMove. A propósito, estou registrando os dois no console dentro do objeto. Só estou fazendo isso para minha preferência pessoal. Dessa forma, é mais fácil visualizá-los no console. Não há nenhuma razão especial por trás disso. Você pode registrá-los no console desse jeito , um após o outro. Mas se você os registrar no console como um objeto, é mais fácil visualizá-los. Voltamos ao jogo, inspecionamos, vemos o console, abrimos esse objeto. Temos currentMove, zero, temos histórico, que é uma matriz. primeiro elemento é esse objeto com quadrados de nulos. Agora, vamos jogar o jogo e ver como isso muda. Eu clico em algum lugar várias vezes e, se eu os abrir, você pode ver que nosso próximo movimento, o índice CurrentMove aumentou e cada movimento seguinte, o índice aumenta. Cresce. Inicialmente, era apenas uma matriz de nulos dentro do primeiro elemento, depois jogamos o jogo, adicionamos isso à matriz do histórico, depois jogamos novamente, adicionamos mais elementos à história, então, dessa forma, podemos rastreá-la. Agora, a questão é: como podemos realmente exibi-lo? Como temos uma matriz, é muito fácil de fazer. Se voltarmos ao componente do aplicativo, aqui precisamos exibi-lo de alguma forma. O que eu sugiro é criar outro componente dentro da pasta do componente, que chamaremos de histórico. Esse será o componente da história de Yan. Vamos exportá-lo por padrão do histórico JSX. Por enquanto, será apenas uma função vazia. Dentro do aplicativo, vou importar o histórico do histórico dos componentes. Vou rolar para baixo e renderizar o componente histórico abaixo do quadro. Eu o salvo e, agora, dentro da história, queremos exibir de alguma forma todas as etapas que fizemos. Na realidade, parece assim. Quando você tem uma matriz de elementos, geralmente deseja que cada elemento represente algo na marcação. Por exemplo, se tivermos uma lista de frutas representada como uma matriz, digamos maçã , kiwi e outra coisa em reação, geralmente é assim. Você pega uma matriz de elementos e mapeia cada elemento da matriz para a marcação JSX. Essa string de maçã se transforma em div, que exibe essa string de maçã, e o mesmo para o resto dos elementos. Para o componente de história, vamos passar nossa matriz histórica como suporte histórico. Dentro da história, podemos sustentá-la usando a distração do objeto adereço. A partir do componente, retornaremos à marcação JSX, os elementos de encapsulamento serão div e usaremos um elemento de lista ordenada para isso. Aqui, precisamos mapear cada elemento de matriz em nosso histórico para a marcação JSX. Vou abrir colchetes para interpolar o JavaScript no JSX. Eu vou fazer history.map. Agora, sem nenhuma lógica extra por enquanto, que exibirá div, então, a partir de d.mapcallback, estou retornando também a marcação JSX e estou dizendo olá aqui. Não importa a mensagem vermelha agora, podemos anexá-la em um segundo. Vamos salvá-lo e ver o que temos. Nós temos olá. Jogamos o jogo e você pode ver que cada elemento da nossa matriz está, e você pode ver que na verdade, mapeado para a div correspondente dentro do HTML. Como temos seis elementos, cada elemento foi mapeado para a div aqui. A propósito, acabei de perceber que também temos algo errado porque exibimos apenas aqueles aqui. Vamos ver. De alguma forma, mudei a lógica. Vamos verificar rapidamente se funciona. Ótimo. Eu estava falando que cada elemento da matriz é mapeado para a div correspondente. Fizemos isso usando o método.map. No entanto, você já percebeu que há um aviso dentro do console e, se eu passar o mouse aqui, será o mesmo, faltando o adereço de chave para o elemento no iterador. O problema é que quando você usa.map dentro da marcação JSX para mapear o elemento da matriz para o JSX, você precisa sempre passar a propriedade chave para os elementos JSX que estão sendo mapeados. A razão para isso é porque o react precisa acompanhar internamente cada elemento que você mapeou para a marcação JSX, caso ele seja alterado no futuro. A razão por trás disso é que, como essa matriz é dinâmica, cada elemento JSX mapeado dentro dessa matriz deve ser representado de forma exclusiva. Para ajudar a reagir com representação exclusiva, identificar de forma exclusiva cada elemento da matriz, precisamos passar o prop chave e o suporte chave deve ser exclusivo para cada elemento. No nosso caso, cada elemento da matriz é um objeto, quadrados e chaves isNext, então não temos nada de especial aqui. O que podemos fazer em casos simples simplesmente passar um índice de elemento de matriz como chave porque ele será exclusivo para cada elemento, porque para o primeiro elemento será zero, para o segundo, um e assim por diante. Ele identificará de forma exclusiva o elemento dentro dessa matriz. Será suficiente para o nosso caso. Vamos pegar esse índice aqui. Primeiro, temos o objeto, com os quadrados e isNext. Não precisamos disso, mas ainda assim, precisamos defini-lo porque, caso contrário, não poderemos pegar o índice, que é o segundo argumento. Como não vamos usar objeto, que vai chamá-lo de sublinhado, e vamos pegar o índice. Para a chave, vamos passar o índice desse jeito. Se eu salvar, se eu atualizar, você pode ver que agora tudo permaneceu o mesmo, mas não temos mais problemas com a chave, porque agora cada elemento dentro da matriz é identificado de forma exclusiva. Agora temos o índice aqui e, na verdade, também podemos interpelá-lo dentro do div e podemos exibir esse índice. O que podemos dizer aqui é que o movimento é o índice. Vamos ver, o que temos? Temos que o movimento é um, o movimento é 2, 3 e 4. Ótimo. Parece muito bom até agora, mas antes de tudo, não queremos mostrar que o movimento é zero. Queremos exibir algo como um novo jogo ou iniciá-lo. Vamos aplicar a renderização condicional aqui. Em vez de fazer isso, vamos perguntar se o índice é igual a 0, então vamos exibir texto de um novo jogo como este. Caso contrário, abriremos os backticks e diremos: vá para mover a hashtag. Aqui, exibiremos o índice. Vamos ver como isso fica. Se eu atualizar a página, teremos um novo jogo por padrão. Se eu jogar, você pode ver que agora temos uma saída muito mais limpa. No entanto, em vez de um novo jogo, talvez digamos assim, vá para o início do jogo. Na verdade, você pode ver que eles não são nem um pouco clicáveis. Vamos converter esse div em elemento de botão do tipo um botão, eu o salvo e agora você vê que ele está quebrado. No entanto, se você se lembra, temos nossos estilos em styles.css. Para essa história, podemos realmente aplicar esse conjunto de classes que já estão escritas aqui. Primeiro, temos history-wrapper, que podemos atribuir ao div history-wrapper. Então, temos a própria história. Este será nosso histórico de listas não ordenadas. Então, dentro da história, cada elemento li será estilizado. Bem, na verdade, certo, porque esquecemos que tem que ser um elemento li. Em vez de botão, vamos digitar li aqui e moveremos esse botão para dentro. Ainda temos essa mensagem para a chave, porque eu disse que a chave deve ser atribuída, deve ser passada somente para o elemento de encapsulamento. O botão está dentro desse elemento. O elemento em si é uma mentira. Preciso passar a chave para o elemento li. Agora eu o guardo. Também temos a classe btn-move aqui. Podemos dar a esse botão className btn-move. Vamos ver o resultado. Parece muito bom até agora. Você pode ver que parece muito, muito melhor. Mas o fato é que não podemos fazer nada agora. Precisamos de alguma forma adicionar o recurso de travessia. A lógica, onde vamos fazer isso será colocada dentro do App jsx. Já temos o estado CurrentMove, que representa em qual etapa estamos atualmente. Aqui dentro, podemos criar uma função que mudará nosso CurrentMove. Vamos chamar essa função de moveTo. Esse MoveTo espera um argumento. Vamos chamar isso de movimento. O que isso vai fazer? Isso apenas atualizará o estado da mudança que está sendo aprovada. Sempre que os chamamos de MoveTo, nós, digamos cinco, ele definirá MoveTo cinco. Agora vamos passar essa função moveTo para a história como um adereço como esse. Dentro da história, vamos pegar o MoveTo. Aqui, podemos anexar esse MoveTo ao evento onclick. Para esse elemento de botão, vamos especificar o manipulador de eventos onclick. Vamos passar uma função que chamará moveTo com o índice desse movimento. Algo parecido com isso. Eu o guardo. Eu atualizo a página. Vamos jogar o jogo. Temos vários movimentos aqui. Sempre que clico aqui, tenho que MoveTo não é uma função, porque eu novamente não salvei o App jsx. Vamos tentar novamente. Eu jogo, clico em “Moves” e você pode ver o estado do jogo realmente muda. Funciona conforme o esperado. Mas, para torná-lo mais fácil de usar, vamos destacar nossa mudança atual em que estamos atualmente. Voltamos ao código e, aqui na história, podemos aplicar classes dinâmicas novamente. Se examinarmos os estilos internos, temos uma classe ativa aqui que pode ser dada ao btn-move. Já temos a classe btn-move, mas ela é estática para todos os elementos. Agora, vamos abrir colchetes. Vamos passar o btn-move aqui. Vamos transformar essa string em um modelo de string para que possamos aplicar a interpolação de strings, que nos dará a capacidade usar JavaScript dentro dessa string. Aqui, vamos fazer uma lógica muito simples. Se index ou, digamos, se currentMove for igual a index, esse elemento estará ativo e esses blocos serão aplicados. Vamos dar uma aula ativa, caso contrário, vamos dar uma aula vazia. Mas não temos currentMove aqui, então teremos que recebê-lo corretamente novamente e dentro do App jsx. Vou passar nosso CurrentMove aqui em cima. currentMove é igual a currentMove. Algo parecido. Vamos economizar e ver. Bem, agora, na verdade está sendo transformado em verde. Vamos inspecionar a marcação HTML. Temos btn-move e temos uma classe ativa. Exatamente o que escrevemos porque o índice do primeiro elemento é zero e currentMove é zero por padrão, esse é nosso estado inicial. Jogamos o jogo e você pode ver como o className muda e o elemento mais recente sempre tem uma classe ativa por padrão. Mas quando clicamos em “Histórico” para percorrê-lo, você pode ver como o className muda. Muito legal. Algo parecido. No entanto, vamos tentar jogar o jogo. Faça uma jogada e depois continue jogando. Você pode ver que algumas coisas estranhas estão acontecendo aqui. O problema é que nosso estado de jogo não está sincronizado com a mudança para a qual voltamos. Isso é problemático. O que queremos fazer sempre que estivermos viajando pela história e, se clicarmos no quadrado, queremos sobrescrever o histórico. Agora, precisamos adicionar outra peça de lógica aqui para conseguir isso. Precisamos detectar se estamos percorrendo a história e, se estamos atravessando, queremos sobrescrever. Caso contrário, queremos mantê-lo como está agora. Vamos voltar ao histórico do App jsx e do conjunto de insights. Vamos primeiro detectar se estamos atravessando. Podemos fazer isso introduzindo a nova variável IsTraversing. A lógica será a próxima. Se nosso currentMove mais 1 não for igual a currentHistory.length. Em seguida, podemos tentar registrá-lo no console e ver se isso é verdade e por que estamos fazendo o movimento atual mais 1. Novamente, vamos consolar um CurrentMove e vamos o console registrar history.length. Vamos chamá-la de duração de sua história. Vamos ver por que precisamos adicionar mais 1 aqui? Se eu abrir o “Console” e jogar o jogo, você pode ver que a duração do nosso histórico é sempre mais 1. Em seguida, o CurrentMove que temos. Isso ocorre porque o tamanho mínimo do histórico é aquele definido pelo nosso estado padrão aqui, enquanto nosso CurrentMove é baseado no índice zero. Para normalizar isso, precisamos adicionar mais 1 ao movimento atual para que eles coincidam um com o outro. Nós simplesmente verificamos. Se “CurrentMove” for igual a qualquer tamanho que tenhamos, então sabemos que estamos na última jogada e não estamos percorrendo a história. Mas se não estamos em nossa última jogada, então estamos atravessando algo assim. Agora, de alguma forma, também precisamos alterar nosso “LastGamingState”. Porque sempre que estamos em nossa última jogada, sempre concatenamos, adicionamos ao histórico atual de jogos até o final da matriz. No entanto, se quisermos sobrescrever, queremos adicionar algo ao histórico, que está no ponto dessa mudança. Não nos importamos com o movimento número três e com o que quer que esteja abaixo dele. Só nos preocupamos com a história neste momento. Precisamos escrever a seguinte lógica aqui. Precisamos modificá-lo. Podemos perguntar, se estivermos atravessando, neste caso, pegue o histórico atual no movimento atual. Caso contrário, pegue o elemento mais recente desse histórico. A lógica com “nextSquareState” não muda, e agora, aqui, em vez do histórico atual concat, também precisamos considerar uma matriz base diferente à qual vamos associar novo estado do tabuleiro de jogo. Vamos criar uma nova variável e chamá-la de algo como base, talvez. Aqui, vamos perguntar novamente: se estamos percorrendo neste caso, por favor, da história atual, corte apenas esses elementos aqui. “Vá para o início do jogo”, “vá para o movimento 1”, “vá para o movimento 2". Nós dividimos do índice zero para o índice do histórico atual do último mais 1. Caso contrário, mantenha o histórico atual como matriz base. Em vez do último, queremos usar o último estado de jogo e, em vez do histórico atual, quero usar o base. Voltaremos a essa lógica em um segundo. Parece assustador, eu sei, especialmente com todos esses ninhos. Mas vamos ver a aparência do nosso jogo agora. Viajamos pela história, está tudo bem. Estamos em movimento número 3, e se eu quiser sobrescrever a história, agora posso fazer isso. Você pode ver que basicamente retiramos o resto da história e a substituímos por nossa nova mudança aqui. Simples assim. Funciona perfeitamente. Agora, e a lógica aqui? Novamente, slice é usado para cortar alguns elementos dessa matriz, da matriz de histórico atual. Nós dividimos do primeiro elemento para o índice do histórico atual de mais 1. Nós apenas pegamos o índice de menos estado de jogo que temos e adicionamos um a ele porque, novamente, temos o “CurrentMove” baseado em zero. Pode ser confuso, mas basta revisar isso algumas vezes e fará sentido. Não é tão simples à primeira vista, mas não há nada muito complexo nisso, e você realmente não precisa pensar demais nisso. Agora temos um histórico de jogos e ele funciona incrivelmente bem. Somos capazes de viajar, podemos ignorar a história sem problemas. Perfeito. Agora, parece que fizemos muito e, na verdade, fizemos muito. Vamos remover esse log desnecessário do console e ver se precisamos adicionar alguma coisa aqui. Talvez possamos adicionar uma mensagem aqui, algo como a história atual do jogo. Vamos ver como fica. Parece assim, o que é bom, e acho que isso será suficiente para este vídeo. Vamos tentar comprometer tudo o que fizemos aqui. Isso é muito. Vou parar o aplicativo, vou adicionar tudo ao palco, vou comprometer tudo e chamá-lo de edição do histórico do jogo. Basicamente, isso é exatamente o que fizemos. Transformamos esse estado em uma matriz. Modificamos nossa lógica e ajustamos tudo à nova forma de estado que introduzimos com a história. GIT commit adicionou o histórico do jogo.Incrível. Talvez, na verdade, vamos adicionar mais uma coisa extra aqui. É completamente desnecessário, mas nos ajudará no futuro vídeo, e vou fazer um pequeno exercício até o próximo vídeo. Vou iniciar o servidor novamente e, o que farei, moverei essa matriz como estado inicial para fora do componente. Vou criá-lo aqui e chamá-lo de novo jogo. Coloquei tudo em letras maiúsculas porque essa é a definição de valor global constante que não vamos mudar, e vou dar a ela essa matriz, desse jeito. Para o estado inicial, vou passar um novo jogo. Na verdade, posso movê-lo para dentro do componente, mas é melhor mantê-lo do lado de fora. A razão para isso é porque, se você se lembrar, sempre que temos uma nova renderização de linha, o JavaScript interno é executado e sempre que o JavaScript é executado, ele cria todas as novas variáveis novamente, e como o novo jogo é algo estático que não precisamos recriar em cada renderização de linha , podemos simplesmente movê-lo para fora. Essa é apenas uma otimização muito pequena, mas nos servirá apenas para o GIT. Por que eles fizeram isso? No próximo vídeo, o que vamos fazer é adicionar um botão no qual clicamos e que reinicia o jogo. Aqui está um pequeno exercício para você até o próximo vídeo. Experimente e faça você mesmo. Crie um botão, exiba-o em algum lugar aqui e, quando você clica nele, ele realmente atualiza o estado do jogo para o estado inicial. Novamente, você joga o jogo, clica no botão, ele atualiza o estado. Tente implementar isso usando a nova variável de jogo que criamos fora do componente. Vou cometer isso e dizer que mudei para novo estado de jogo fora do componente do aplicativo, vou enviar tudo para master e, no próximo vídeo ele nos ajudará a implementar a redefinição do jogo. Tente se exercitar. Nos vemos na próxima. 51. 12 Adicionando o botão de reinicialização do jogo: Ei, como foi seu exercício do último vídeo? Você conseguiu fazer isso? Vamos ver. Neste vídeo, adicionaremos um botão que redefinirá nosso estado de jogo. Vamos embora. Então, aqui na marcação, bem no topo da história atual do jogo, vamos adicionar um elemento de botão do tipo botão e vamos dizer que ele iniciará um novo jogo. Então, quando clicamos nele, ele deve fazer alguma coisa. Vamos colocar o manipulador onClick aqui e, para esse evento onClick, vamos especificar onNewGameStart, e esse onNewGameStart será uma função que criaremos aqui e essa função, a única coisa que ela fará, apenas atualizará o estado. No vídeo anterior, no final, movemos o novo jogo para a parte externa do componente e isso nos ajudará agora. Agora podemos realmente ligar, definir o histórico e passar por um novo jogo, que é nosso estado inicial. Além do histórico, também precisamos reiniciar o contador da nossa jogada atual. Vamos seguir em frente e chamar definir movimento atual e colocá-lo de volta para zero. Vamos ver. Se eu salvar, eu jogo o jogo, clico em “Iniciar novo jogo”. Tudo foi atualizado agora. No entanto, não tem estilo e, se examinarmos o estilo CSS, temos aqui a classe.btn-reset. Vamos continuar e usá-lo. Então, para esse botão, vou passar o nome da classe e vou passar btn-reset. Mas se você ver, ele também tem a classe ativa aqui. O que eu queria fazer quando apresentei essa classe ativa é que sempre que tivéssemos um vencedor, esse botão se tornasse ativo. Então, vamos aplicar a lógica dentro do nome da classe aqui. Como vamos aplicar JavaScript, novamente, usamos colchetes e, antes de tudo, esse será um modelo de string com acentos. Vamos dar a ela a classe estática btn-reset e, em seguida, abriremos as aspas de interpolação de strings e, dentro desses colchetes para interpolação de strings, vamos perguntar. Então, se tivermos um vencedor, por favor, dê a ele uma aula ativa, caso contrário, mantenha-a vazia. Algo assim e agora vamos ver. Então temos esse lindo botão aqui e se jogarmos o jogo, e vamos ter um vencedor, e sempre que tivermos um vencedor, esse botão fica ativo. Se percorrermos a história, tudo voltará a funcionar conforme o esperado. Parece bom. Isso é tudo para reiniciar o botão. Como você pode ver, nada complicado, então vamos em frente e nos comprometer. Vou adicionar essas mudanças ao estado do estágio e depois vou me comprometer. A mensagem de confirmação será adicionada ao botão de reinicialização do jogo ou iniciará um novo jogo. Incrível. Eu envio tudo para o GitHub e vejo você no próximo vídeo. 52. 13 Destacando o vencedor do jogo (combinação vencedora): Olá a todos. Neste vídeo, o que vamos fazer? Podemos exibir a combinação vencedora caso tenhamos um vencedor, e também, mas mudaremos a cor dos quadrados porque agora eles são pretos. Agora, talvez vamos começar com as cores primeiro. Se formos para o quadrado dos componentes, a lógica aqui será praticamente a mesma que temos dentro da mensagem de status. Se você se lembra, aplicamos o className dinâmico aqui. Se o vencedor for X, o texto será verde, caso contrário, será o texto laranja. As classes que definimos aqui dentro dos estilos basicamente fornecem a cor ao elemento definido pela variável SAS aqui. Aqui dentro do quadrado, vamos simplesmente convertê-lo em expressão JavaScript. Vamos mudar as aspas de aspas duplas para acaspas. Vou perguntar se nosso valor é X, então vamos nosso valor é X, exibir o texto verde, caso contrário, vamos exibir o texto laranja. Simples assim, nada complicado. Você pode ver agora que tudo se transformou em um lindo sistema de cores. Se clicarmos, se jogarmos, funciona. Ótimo. Agora, vamos pensar em como podemos realmente destacar os quadrados vencedores. Para destacar os quadrados vencedores, precisamos conhecer os quadrados. Precisamos conhecer seus índices. Precisamos saber que, se tivermos vencedor X para essa combinação vencedora, teremos quadrados vencedores e Índice 2. Então temos 0, 1, 2, 3, Índice 4 e Índice 6. Estes são nossos quadrados de ganhos. Calculamos o vencedor dentro da função calcular o vencedor e retornamos apenas o quadrado vencedor, somente seu valor. No entanto, a partir dessa função, também podemos retornar quadrados vencedores. Porque aqui comparamos todas as combinações vencedoras possíveis. Já temos essas variáveis a, b e c, elas estão estruturadas aqui, que representam índices vencedores, a combinação vencedora. A partir dessa função de cálculo do vencedor, podemos retornar um objeto em vez de apenas nulo ou o vencedor. Podemos devolver um objeto com o vencedor e os quadrados vencedores. Caso não tenhamos nenhum vencedor, agora retornaremos nulo. Mas vamos transformá-lo em um objeto. Retornaremos vencedor ou nulo, e os quadrados vencedores serão uma matriz vazia. Mas caso tenhamos um vencedor, devolveremos um objeto, o vencedor serão quadrados c ou quadrados a ou quadrados b, não importa. Mas para ganhar quadrados, retornaremos as linhas i ou podemos realmente devolvê-las assim. Podemos criar uma nova matriz e depois especificar explicitamente que estamos retornando a, b e c, ou podemos especificar uma linha a linhas i. Agora voltamos para J6. Agora, esse vencedor é um objeto. Se eu destacar, também me mostra um objeto. Eu posso usar essa estrutura aqui. Da estrutura de ID do objeto que retorna, chave vencedora e quadrados vencedores. Vencedor e quadrados vencedores. Agora podemos passar esses quadrados vencedores para o componente do tabuleiro como um suporte e lidar com essa lógica lá. Vou passar os quadrados vencedores para o tabuleiro e, dentro do tabuleiro, vou pegar os quadrados vencedores e para aquele componente quadrado que entraria aqui. Posso passar um adereço que diz se esse quadrado é um quadrado vencedor ou não e, em seguida, aplicar alguma lógica dentro do componente quadrado. No render square, vou verificar se o quadrado é um quadrado vencedor. Vou criar apenas uma variável dentro do quadrado de renderização e chamá-la de quadrado vencedor. Os quadrados vencedores são uma série de índices vencedores. Como 0, 1 e 2. Por exemplo, vamos pegar essa combinação. Precisamos verificar se a posição desse quadrado está dentro da matriz de quadrados vencedores. Se isso for verdade, então sabemos que o quadrado faz parte da combinação vencedora. Podemos simplesmente verificar os quadrados vencedores. Inclui esta matriz que inclui a posição global do método. É isso. Então, podemos passar esse quadrado vencedor enquanto eu desço para o componente quadrado. Se abrirmos o componente quadrado, vamos movê-lo aqui. Dentro do quadrado, desde que passamos, está o quadrado vencedor. Pegamos esse quadrado vencedor do objeto de adereços. Aqui podemos aplicar outro className dinâmico com base nesse quadrado booleano vencedor. O método dot include retorna como um booleano, o que indica se essa matriz inclui esse elemento. Já aplicamos o sobrenome dinâmico aqui com base no valor. Podemos fazer exatamente o mesmo com o quadrado vencedor. Vou apenas estender essa string com outra interpolação e vou perguntar se esse é o quadrado vencedor. Por favor, aplique um pouco de className e algum className será, se abrirmos estilos, CSS, dentro temos essa classe vencedora. Essa classe vencedora anexa a animação de texto em escala definida aqui, que aumenta o tamanho da fonte de forma infinita. Vamos voltar à praça. Se for um quadrado vencedor, atribuímos a classe vencedora. Caso contrário, anexamos uma classe vazia. Vamos ver se funciona e depois disso, faremos algo sobre esse slide, porque você vê que ele parece um pouco confuso agora. Vamos ter um vencedor. Boom. Na verdade, funciona. Basta olhar isso. Temos tudo pronto aqui. Muito legal, não é? Sempre que percorrermos a história, e se voltarmos aos últimos movimentos, a animação estará lá. Se inspecionarmos a marcação, teremos a classe vencedora anexada a cada quadrado que faz parte da combinação vencedora. Muito legal. Agora vamos fazer algo com essa corda porque, bem, ela parece um pouco confusa. Na verdade, não podemos fazer muito sobre isso. Podemos dividi-lo em várias variáveis e depois combiná-lo, talvez algo como colorClassName. Então, podemos simplesmente cortar essa lógica daqui, colocá-la assim, então talvez possamos dizer algo como WinningClassName, e então fazemos exatamente o mesmo. Nós apenas cortamos essa lógica, colocamos aqui. Em vez de usar essa lógica em linha, como fizemos agora, o que vai passar a variável. Isso será colorClassName. Interpolamos esse valor de variável dentro dessa string e fazemos o mesmo aqui, WinningClassName. Agora, parece muito mais limpo. Basicamente, separamos a lógica em várias linhas. O que você preferir. Se você quiser torná-lo um pouco mais limpo dessa maneira, tudo bem. Se você gostou da maneira bagunçada, fique à vontade para fazer isso. Algo assim, temos a combinação vencedora, que foi destacada na história do jogo. Ótimo. Acho que no próximo vídeo, faremos os preparativos finais e daremos mais algumas coisas, talvez apenas texto adicional, mais estilos. Finalmente, teremos o aplicativo preparado para ser implantado em uma hospedagem. Incrível. Agora, antes de terminarmos o vídeo, vamos remover comentários, registros do console e confirmar tudo. Vamos dar uma visão geral do que fizemos para modificar o cálculo quando o retorno retornou esse valor para um objeto com duas chaves, quadrados vencedores e vencedores, depois passamos esses quadrados vencedores para o componente do tabuleiro. Dentro do tabuleiro, detectamos se o quadrado que percorremos é um quadrado vencedor e, com base nesse componente do quadrado interno, aplicamos dinamicamente nomes de classes para alternar a animação. Algo parecido. Vamos e comprometer tudo. Git, adicione isso. A mensagem será destacada com a combinação vencedora. Incrível. Vamos empurrar tudo. Até a próxima, nos vemos lá. 53. 14 toque final: Olá. Neste vídeo, daremos um toque final em nosso aplicativo antes da implantação. Bem, se usarmos nossos estilos, na verdade, aqui, para o elemento corporal, aplicaremos essa fonte Roboto, mas na verdade não a temos em nosso PC. Não o temos em lugar nenhum. De onde veio isso? O fato é que não foi realmente aplicado. Vamos consertar isso. No convidado que compartilhamos conosco, temos o HTML de índice aqui com algumas propriedades. Se olharmos dentro do nosso índice HTML, não temos esse link para a folha de estilo que temos aqui. A folha de estilo, o que ela fará, baixará a fonte Roboto das APIs do Google. Vamos apenas incluir isso e, com essa linha, se atualizarmos o aplicativo, nada mudará porque não executamos o servidor de desenvolvimento. Eu executo o servidor, eu volto para o aplicativo. Agora, na verdade, temos a fonte Roboto aplicada. Se eu remover essa linha, você verá as mudanças na família da fonte. Mas assim que não carregamos a fonte que especificamos na folha de estilo, tudo funciona. Ótimo. Agora vamos adicionar o título ao nosso aplicativo na parte superior. Aqui dentro do aplicativo, logo acima do componente de mensagem de status, exibiremos uma tag de título h1 simples e informaremos o TIC TAC TOE. Para torná-lo mais atraente, podemos mudar a cor do TAC. Vamos envolvê-lo em um elemento de extensão e dar a ele um nome de classe de texto verde. Vamos salvá-lo. Agora parece muito melhor, e acho que devemos realmente remover a propriedade font-weight bold título atual do histórico do jogo. Podemos fazer isso aplicando estilos embutidos. Bem, o que é ótimo. Nós não ouvimos isso, ou não o vimos antes. A única maneira de aplicarmos estilos até agora no aplicativo foi usando a propriedade de nome da classe. Os nomes das classes são definidos aqui dentro do arquivo SaaS. No entanto, e se não tivermos nenhum arquivo CSS ou arquivo SaaS? Como podemos aplicar estilos? Bem, sem o React em apenas um arquivo HTML, podemos ter dois tipos de estilos. Podemos dar aos elementos um nome de classe ou transmitir estilos embutidos. O mesmo que podemos fazer aqui no React. Para esse histórico do jogo, podemos passar a propriedade de estilo e a propriedade de estilo deve ser um objeto. Devemos especificar estilos usando JavaScript, não com CSS, mas com JavaScript. Vamos escrever CSS com a ajuda do JavaScript, e isso é chamado de estilo embutido. Queremos remover o peso da fonte em negrito do elemento de título que temos aqui. O estilo do elemento terá o peso da fonte normal. Aqui, precisamos passar o peso normal da fonte, desse jeito. Vamos ver se funcionou. Se inspecionarmos o elemento, posso ver o estilo e o peso da fonte normais. Esses são estilos embutidos. O objeto JavaScript que passamos aqui foi convertido para essa string de estilo embutida. Você pode ver que eu não especifiquei o traço entre as palavras de fonte e peso porque, ao especificar estilos embutidos, é necessário usar a sintaxe camel case. Se sua propriedade tem um traço entre as palavras, ou tem espaços, seja o que for, você sempre a substitui por uma caixa de camelo. Por exemplo, família de fontes. Você teria uma família de fontes em forma de caixa de camelo. Algo parecido. aplicar estilos embutidos em outro lugar. Se formos ao histórico de componentes, temos este botão aqui que representa esse item na lista. Vamos torná-lo ousado sempre que estiver ativo. Se abrirmos nomes de classes, vamos ver se está em negrito. Na verdade, é ousado. O que poderíamos ter feito se não usássemos nenhum estilo, poderíamos ter feito o seguinte se entrássemos na história. Aqui eu teria passado pelo estilo e especifico, você pode ver colchetes duplos aqui. primeiro colchete é especificar que usaremos JavaScript dentro e o segundo em seus colchetes significa que esse será um objeto para o qual passaremos um objeto. É por isso que temos colchetes duplos aqui. Propriedade de peso da fonte, poderíamos ter perguntado, se o movimento atual for igual ao índice, ela estará em negrito, caso contrário, normal. Se não tivéssemos essas classes, vamos removê-las e ver se funcionou. Se eu aumentar o zoom, eu jogo o jogo, você pode ver que o elemento para qual essa condição é verdadeira fica em negrito. Basicamente, nosso movimento atual se torna ousado. Caso contrário, o peso da fonte é normal. Não precisamos dele para esse elemento específico porque ele já foi gerenciado dentro do CSS. Você pode ver que o peso da fonte está em negrito quando está ativo, então não precisamos de estilos embutidos aqui. Acho que é isso. Eu diria que terminamos nossa inscrição. Temos todas as funcionalidades, temos todos esses estilos. Tudo funciona perfeitamente e tem uma aparência incrível. Sinta-se à vontade para modificar qualquer coisa, à vontade para aplicar seus próprios estilos, sinta-se à vontade para brincar com isso, estendê-lo ou talvez mudar alguma coisa. Não há requisitos estritos de que isso deva ser feito especificamente dessa maneira. Você é o desenvolvedor aqui e é você quem decide. Se você precisar alterar o título aqui, sinta-se à vontade para alterar o título. Se você quiser incluir metatags extras dentro da cabeça, sinta-se à vontade para fazer isso. Nós terminamos aqui. Esse é o estado final do nosso aplicativo. No próximo vídeo, falaremos sobre implantação. Mas antes de terminarmos esse vídeo, vamos encerrá-lo e comprometer tudo. Vou abrir o terminal; vou confirmar tudo. Vou especificar as alterações que fizemos, então adicionamos a fonte e adicionamos o título. Foi adicionado o título do jogo TIC TAC e incluiu a fonte Roboto. Eu envio tudo novamente para o GitHub. Como sempre, nos vemos na próxima. 54. 15 Implantação para surtir: Olá. Nesta etapa, concluímos nosso precioso aplicativo. Está lindo. Ele tem todas as funcionalidades. Agora, é hora de compartilharmos esse aplicativo com o mundo exterior. Queremos publicá-lo na Internet para que possamos ter o link real, o URL real que podemos dar aos nossos amigos. Como podemos fazer isso. Existem vários serviços diferentes que podem hospedar nossos arquivos estáticos gratuitamente ou não gratuitamente. Vamos usar serviços gratuitos. Mas a questão é: como exatamente isso acontece? Quando vamos executar o script de construção definido no pacote Json, vite construirá nosso aplicativo e produzirá arquivos estáticos, HTML, CSS, JavaScript e imagens, se tivermos algum. Depois, podemos pegar essa pasta e entregá-la a um provedor de hospedagem. Esse provedor de hospedagem exibirá esses arquivos em algum lugar seus servidores e os exporá publicamente por meio de um URL gerado automaticamente. Um dos serviços que podemos usar para hospedar nosso aplicativo gratuitamente, hospedar nosso HTML, CSS JavaScript gratuitamente, ele sempre será gratuito e é muito simples. O serviço se chama Surge. Você pode acessá-lo acessando surge.sh. O legal do Surge em sua simplicidade é que você não precisa de nenhuma configuração extra. O que você precisa fazer é instalar apenas o pacote global surge e, é instalar apenas o pacote global surge em seguida, usando o comando Surge, você pode implantar o aplicativo dessa forma. Vamos seguir em frente e fazer isso. Surto global de instalação do NPM. Vou colá-lo no meu terminal. Ele instalará o pacote de sobretensão global. Diz, uma vulnerabilidade crítica de gravidade. Bem, você não precisa se preocupar com isso. Sempre que você vê vulnerabilidades, isso pode ser bastante comum, especialmente com pacotes globais. Bem, esse é o problema do pacote. O que podemos fazer sobre isso e quais são as vulnerabilidades? Vulnerabilidades no código que baixamos desse pacote e ele pode ser malicioso. Mas você não precisa levar isso a sério. Na maioria das vezes, no mundo do NPM, pacote é atualizado talvez uma vez por dia, talvez duas vezes por dia. Mas nem sempre é possível acompanhar as mudanças, com as atualizações. Você pelo menos verá uma vulnerabilidade crítica uma vez. Suas opções são, primeiro, não fazer nada e atualizar para a versão mais recente e esperar que o autor do pacote tenha corrigido a vulnerabilidade. A segunda opção é não usar esse pacote. No nosso caso, não podemos fazer muita coisa e é por isso que concordamos. Agora, temos o pacote de pesquisa global instalado e ele diz que precisamos executar o comando de pesquisa. Se eu fizer isso, ele solicitará que eu faça login ou crie uma conta. Vou apenas inserir meu endereço de e-mail e depois inserir minha senha. Eu já tenho uma conta, então ela me conectará. Mas, no seu caso, isso criará uma nova conta para você. Agora, isso me incentiva a iniciar o projeto, mas eu realmente não preciso de nada no momento. Então, vou fazer o Controle C para interromper a publicação do meu aplicativo. Primeiro, precisamos construí-lo. Vou executar o script npm run build e o vite produzirá a versão mais recente do nosso aplicativo. Ótimo. Agora está lá. Parece minimizado, aglificado e tudo mais. Agora, queremos pegar a pasta Dist e implantá-la para pesquisar. Então, usamos o comando de pesquisa e, em seguida, especificamos o caminho para a pasta que queremos implantar em relação à nossa navegação atual. Como nossa navegação atual é tictactoe-vite, nossa pasta está localizada nessa pasta no mesmo diretório. Não precisamos ficar loucos com isso. Só precisamos especificar o nome da pasta que queremos implantar. No nosso caso, essa é uma pasta chamada Dist. Se eu fizer isso, eu apenas executo o Search Dist. Ele me pede um domínio. Portanto, sempre que você implantar no Surge, ele sempre será implantado em um subdomínio. Sempre será algo dot surge dot sh. Você não pode alterar a parte do surge.sh, mas pode escolher um subdomínio exclusivo que não está sendo usado até agora. Por padrão, o surge gera automaticamente um subdomínio que está disponível, mas você pode alterá-lo. Talvez vamos chamá-lo de tictacgame.surge.sh. Eu escolho esse nome. Mas, no seu caso, você terá que criar seu próprio subdomínio, porque se tentar implantar em um subdomínio que já foi usado por outro usuário do Surge, você terá permissão negada ou algo assim. Isso fará com que sua solicitação seja abortada. Portanto, certifique-se de escolher algo único e continue com isso. Eu escolho tictacgame.surge.sh. Eu implanto e agora ele está publicado em tictacgame.surge.sh. Agora eu posso pegar esse link e ir até lá. Como você pode ver agora, meu aplicativo está ativo. Tem link HTTPS. Isso significa que o certificado SSL está presente. É gerenciado pela Surge. Não precisamos nos preocupar com isso. Tudo funciona. Agora você pode pegar esse link e compartilhar com seus amigos. Basta olhar isso. Quão legal é isso? Ótimo. Agora, para referência futura, talvez queiramos simplificar o processo de implantação. E se eu quiser mudar alguma coisa e depois reimplantar novamente exatamente no mesmo domínio? Então, neste caso, o que eu preciso fazer fazer minhas novas alterações, introduzir novas alterações no aplicativo. Em seguida, vou executar o npm run build novamente para produzir uma nova pasta dist atualizada e, novamente, terei que executar o surge dist e entrar no mesmo domínio. No entanto, quero torná-lo o mais simples possível. Então, por que não criamos outro script dentro do pacote Json e o chamamos de deploy. Vamos seguir em frente e criar um novo script de implantação. Isso fará duas coisas. A primeira coisa é que ele executará o comando build, npm run build, e logo em seguida, usando a lógica e o operador, podemos encadear o comando que será executado após o npm run build. Então, queremos executar o surge dist e o domínio que temos até agora. Surge, o nome da pasta que queremos implantar, dist e, em seguida, o domínio. Sim, posso passá-lo para o comando surge como argumento e funcionará. O Surge entenderá que queremos implantar esse nome de domínio. Portanto, podemos eliminar o HTTPS e manter apenas o nome de domínio assim. Agora, se eu tentar mudar alguma coisa, talvez dentro do aplicativo, vamos verificar rapidamente se funciona. Então, vamos mudar tic para outra coisa, e agora eu executo npm run deploy. Você verá que ele pega o comando build e, logo em seguida, pega o comando surge. Ele foi implantado, diz que foi publicado em titacgame.surge.sh. Se eu atualizar. Agora, você vê novas mudanças. Legal, certo? Tudo bem. Vamos reverter tudo aqui e reimplantar novamente. Novamente, produziu uma nova construção. Novamente, ele foi implantado e publicado novamente nesse subdomínio. Incrível. É isso. Agora você tem nosso aplicativo online. Você pode ir em frente e compartilhá-lo com o mundo. Vamos confirmar nosso script de implantação que introduzimos, git commit adicionou o script de implantação. Então, parabéns, construímos esse jogo muito legal aqui sem muito esforço. Nós o publicamos no serviço Surge. Então, agora ele está disponível na Internet e sempre será gratuito. Ele será hospedado gratuitamente para sempre e agora podemos nos orgulhar disso. No próximo e último vídeo sobre o Tic-Tac-Toe, vamos resumir exatamente o que aprendemos durante esses vídeos, quais conceitos entendemos, o que podemos fazer agora com nosso conhecimento. Nos vemos lá. Parabéns pela implantação. 55. 16 resumo: Olá de novo. Neste vídeo, vamos resumir rapidamente o que exatamente aprendemos até agora durante o jogo tic-tac-toe. Vamos embora. Se olharmos nossa estrutura, já podemos dizer que sabemos como usar o Vid. Conhecemos as ferramentas de front-end que podem construir nosso projeto. Se examinarmos o pacote JSON, podemos ver que também aprendemos sobre hospedagem e como podemos hospedar o aplicativo gratuitamente. Você pode escolher no Google qualquer serviço de hospedagem que permita hospedar arquivos estáticos, HTML, CSS e JavaScript e ver como aplicá-los caso precise de uma alternativa para pesquisar. Nós conhecemos os serviços de hospedagem agora. Se olharmos dentro da pasta de origem e se olharmos dentro do JSX principal, podemos dizer que usamos o React 18. Essa é a API dos cabeçalhos do React 18 e é diferente do React 70. Aprendemos como usar a versão mais recente do React aqui. Se olharmos dentro do App JSX, podemos ver uma lógica diferente aqui. Já sabemos o que é estado, como podemos gerenciar o estado, como podemos atualizar o estado e por que ele é necessário. Também sabemos qual é o valor derivado desse estado e por que realmente não precisamos criar outro estado para gerenciar esses cálculos, como vencedor ou talvez como um tabuleiro de jogo. Também sabemos que a atualização de estado ou função pode ser chamada de várias maneiras, seja com o retorno de chamada sempre que precisarmos definir um novo estado a partir do valor do estado atual ou apenas com uma chamada normal sem retorno de chamada, apenas o valor. Nós conhecemos a marcação JSX agora. Sabemos como aplicar nomes de classes. Conhecemos estilos embutidos apenas com o objeto de estilo para que possamos escrever CSS usando JavaScript. Sabemos como aplicar estilos dinâmicos simplesmente usando modelos de string e um pouco de JavaScript. Sabemos como passar adereços. Os prompts são basicamente os atributos dos componentes que você pode usar para passar dados para o componente. Aprendemos sobre renderização condicional. Sabemos que podemos renderizar marcação JSX com base em alguma condição e podemos fazer isso de várias maneiras. Podemos fazer isso em linha usando o operador AND diretamente dentro do JSX, ou talvez possamos criar uma função auxiliar e escrever a lógica interna. Vamos ver o que mais temos aqui. Se olharmos para dentro da praça, já conversamos sobre isso. Se olharmos para dentro da história, ainda não conversamos sobre isso. Também sabemos agora que podemos pegar uma matriz e mapear cada elemento da matriz para a marcação JSX. Caso precisemos exibir listas, usamos o método de mapa de pontos. O método de mapa de pontos mapeia cada elemento da matriz para a marcação JSX se o usarmos dentro do JSX. Sempre que fazemos isso, lembramos que sempre precisamos passar a chave para o elemento de encapsulamento porque o React precisa identificar cada elemento mapeado dentro do JSX. Eu acho que é isso. Já aprendemos muitos conceitos sobre o React. Confie em mim, todos esses conceitos que você experimentou formam a base necessária para criar qualquer coisa com o React. Tudo o que você vê aqui está presente em qualquer outro aplicativo React. Se você se sentir flexível com isso e puder aproveitar isso, isso é incrível. Isso significa que, no futuro, você não terá problemas para criar nenhum tipo de aplicativo. Parabéns. Com essa boa nota, vamos encerrar o projeto tic-tac-toe. vejo na próxima vez. 56. 17 Extra: Olá, pessoal. Na verdade, esqueci um pequeno detalhe sutil para adicionar ao nosso aplicativo. Isso é sobre estilos. É sobre esses círculos que vemos em segundo plano. Não os vemos agora porque, bem, não os adicionamos, mas eu esqueci de fazer isso. Dentro do Style CSS, você tem a classe BG balls, que cuida dos círculos de fundo. Só precisamos criar um elemento vazio em algum lugar dentro da marcação do aplicativo. Digamos que uma div vazia. Damos a ela um nome de classe de bolas BG. Se atualizarmos a página, veremos que os círculos aparecem em segundo plano, são responsivos e têm uma aparência muito bonita. Desculpe por isso. Não se esqueça de reimplantar o aplicativo e omitir essa alteração. Vou seguir em frente e adicionar círculos de fundo. Em seguida, o NPM execute deploy. Os scripts de implantação que definimos internamente [inaudível]. Tudo bem, até mais. 57. Visão geral do aplicativo do Box Office: Olá, bem-vindo ao Box Office. Neste vídeo, gostaria de apresentar rapidamente o projeto, o que isso vai ser. No momento, você está vendo a bilheteria. Este será um aplicativo de busca de filmes e atores. Você poderá pesquisar filmes ou atores, e os dados que você procura serão obtidos da API. Por exemplo, na entrada, vou digitar algo como garotas e, quando pressiono “Enter” ou pressiono o botão de pesquisa, vejo os resultados. Todos esses resultados serão obtidos do servidor de API externo, que está disponível publicamente. Poderemos estrelar shows. Quando clicarmos em um programa, veremos aquela animação legal. Para que o usuário entenda que esse programa agora está marcado como favorito, podemos clicar em Leia mais e, nesse caso, uma nova página será aberta em uma nova guia. Aqui poderemos ver todas as informações que recuperamos da API; detalhes, temporadas, elenco, tudo sobre o programa. Aqui, voltamos para sua página inicial botão Aqui, caso precisemos voltar. Vamos fechar essa guia. Agora, como estrelamos programas aqui, eles estarão disponíveis em outro lugar. Eles estarão disponíveis na guia Iniciar. Quando navegamos aqui, todos os programas que selecionamos anteriormente agora aparecem aqui nessa página. Mesmo que eu feche o navegador, feche a guia ou atualize a página, nossos programas ainda estarão lá. Eles não são armazenados em um banco de dados, mas são salvos no armazenamento do navegador, especificamente no armazenamento local. Vamos voltar para o Início e você pode ver que a entrada ainda está lá. O mesmo acontece com a entrada, assim como os programas que marcamos estrela são salvos em algum lugar dentro do navegador, o mesmo que fazemos com a entrada aqui. Se eu atualizar a página, a entrada ainda estará lá. Além disso, temos essa caixa de rádio aqui, botões de rádio, se mudarmos para atores e depois procurarmos algum nome, por exemplo, como James. Em vez de shows, agora veremos os atores. Novamente, a mesma API, mas ao contrário dos programas, os atores não têm sua própria página porque não recebemos muitas informações da API. Isso é suficiente, apenas cartões para pessoas, para atores, e esse aplicativo também é um aplicativo web progressivo. Isso significa que nosso aplicativo agora pode ser instalado como se fosse um aplicativo nativo, esteja em um desktop ou dispositivo móvel. Por exemplo, aqui no canto superior direito, tenho esse botão de instalação e, se eu clicar nele, ele solicitará que eu instale este site como se fosse um aplicativo. Se eu clicar em Instalar, logo em seguida, serei, digamos, redirecionado ou aberto em uma nova janela que funciona sozinha e esse será meu aplicativo. Logo depois disso, se eu voltar para minha área de trabalho aqui, vejo isso, agora posso. Este é meu atalho para o aplicativo. Se eu fechá-lo e abri-lo novamente, será aberto em uma guia separada e funcionará exatamente da mesma maneira. Muito legal. Eu diria que é isso, esse é o nosso aplicativo, vai ser muito divertido. Nos vemos lá. 58. 02 Criando o projeto com o Create React App: Ei, aí. Como você se sente depois do tic-tac-toe? Pronto para continuar? Desta vez, vamos trabalhar no Box Office, um aplicativo web onde podemos pesquisar diferentes filmes e atores. Vamos embora. Para o Box Office, vamos usar o Create React App. É um clichê muito popular do React, que nos permite criar arquivos de projeto. No tic-tac-toe, usamos uma ferramenta chamada Vite. Desta vez, vamos usar o Create React App. Create React App é como o Santo Graal de todos os modelos para aplicativos React. A razão por trás disso é porque Create React App é mantido pela equipe do React. É o que podemos chamar de modelo oficial do React. Você tem uma pergunta, por que escolhemos Create React App quando usamos o Vite no tic-tac-toe? A resposta para isso é muito simples. Só porque não há nenhuma razão real por trás dessa decisão. Seja qual for a sua escolha, você ficará bem. Mas, para fins de nossa negociação, queremos explorar o maior número possível de opções e ver o que podemos fazer e o que podemos alcançar usando modelos diferentes. Todos eles serão praticamente iguais. Eles podem ser diferentes dependendo do quanto você pode usar com a personalização. Mas, no geral, eles são muito parecidos. No momento, estou no site oficial do modelo do Create React App. O que podemos fazer é ir para Começar. A partir daqui, já temos a seção Quick Start, onde podemos simplesmente copiar esse comando. Mas nosso aplicativo de bilheteria será algo chamado de aplicativo web progressivo. Vamos falar sobre aplicativos web progressivos. O que é isso? Por que é legal e por que precisamos dele ou talvez não precisemos dele? Vamos abordar tudo isso mais tarde no Box Office, mas precisamos tomar uma ação específica antes de criar o aplicativo. Mais tarde, podemos usá-lo. Se rolarmos para baixo e formos para Modelos, podemos ver que podemos executar o comando Create React App com o sinalizador de modelo. Se formos para o Uso Avançado ou para o desenvolvimento, deixe-me ver onde está, criando seu aplicativo, criando um aplicativo web progressivo. Se formos para essa seção aqui, ela nos dará esse comando que podemos executar com o modelo conforme especificado, que será um aplicativo web progressivo. Isso é exatamente o que vamos copiar e usar para criar novos arquivos de projeto. Então, o que eu vou fazer é ir para a pasta onde eu gostaria de ver meu projeto. Esta vai ser a pasta de embrulho que eu tinha no vídeo anterior. A abordagem é a mesma. Você precisa executar esse comando na pasta em que gostaria de ver a pasta do seu projeto. Eu vou abrir o Git Bash, você abre seu terminal. Pode ser qualquer coisa. Não teremos problemas de interatividade se estivermos no Windows com o Git Bash. Vou para o disco d depois para a pasta do aplicativo. Aqui, vou colar esse comando em vez do meu aplicativo aqui. Vou escolher o modelo Box Office, o modelo Create React App PWA. Quando eu pressiono enter, o comando será iniciado. Levará alguns minutos para criar todos os arquivos necessários. Ele não apenas criará arquivos, mas instalará todas as dependências do pacote Jason, então esse comando pode demorar um pouco. Enquanto estiver no processo de instalação, vamos falar sobre a diferença entre o Vite e o Create React App. No tic-tac-toe, usamos o Vite. Vite é basicamente uma configuração em cima do pacote de módulos com o Create React App. É quase o mesmo. Create React App é uma configuração em cima de um bundler de módulos chamado Webpack. Embora o Vite possa ser usado para qualquer biblioteca de front-end, para qualquer projeto de front-end, Create React App visa apenas o React. Vite usa roll-up. Create React App usa o Webpack, e ambos são configurações em cima desses buflers de módulo. Não há muita diferença no que escolher. A resposta é que é muito subjetivo o que escolher. Pessoalmente, prefiro o Vite, mas o Create React App tem seu próprio conjunto de benefícios, por exemplo, eles têm esse suporte progressivo a aplicativos web pronto para uso, o que é ótimo e se adapta perfeitamente que é ótimo e se adapta perfeitamente às necessidades do nosso projeto. Deixe-me voltar aqui para o terminal. Eu posso ver que tudo foi instalado. Eu posso ver a mensagem de sucesso e a mensagem de boas-vindas. Se eu abrir minha pasta aqui, tenho o Box Office e dentro dos meus arquivos de projeto. Agora, vou abrir o VS Code e, dentro do VS Code, vou abrir esse laboratório de pastas. Isso vai ser bilheteria. Aqui temos algumas coisas que são um pouco diferentes das que tínhamos antes no tic-tac-toe. Vamos falar sobre isso em um segundo. Antes de prosseguirmos, vamos abrir o convidado que você compartilhou com você. A partir daqui, vamos configurar o Prettier e o ESLint. A configuração será praticamente a mesma do tic-tac-toe, mas um pouco diferente. Primeiro, vamos copiar a configuração do ESLint. Vou criar o eslintrc. Copie tudo aqui, o mesmo que farei com Prettier. No ESLint, o que temos aqui? Exatamente a mesma configuração do tic-tac-toe, mas também temos o plugin aqui, React Hooks, e apenas algumas regras definidas aqui. Em seguida, precisamos instalar dependências. Assim como antes, precisamos instalar a configuração ESLint Prettier. O plugin Prettier que estendemos, que precisamos instalar o plug-in ESLint React e também o plugin React Hooks. Vou copiar esses plug-ins aqui. O comando de instalação será eslint-config-prettier, eslint-plugin-react e eslint-plugin-react-hooks. Além disso, preciso instalar as ferramentas em si. Preciso instalar o Prettier e o ESLint. Ótimo. Agora, vamos aguardar a instalação. Eu já tenho seis vulnerabilidades de alta gravidade. Bem, então o que vou fazer a seguir. Em seguida, vamos inspecionar o que exatamente temos no pacote Jason. Vamos começar com os scripts. Assim como eu disse, o Create React App é uma configuração sobre empacotador de módulos subjacente do Webpack. Essa configuração oculta é exposta a nós por meio do pacote de scripts React, que é distribuído por meio do NPM. Assim como temos o beat distribuído por meio do NPM, temos scripts React. É por isso que, em nossos scripts, temos scripts do React iniciando, construindo, testando e ejetando. Quais são esses scripts? No Tic-tac-toe, temos o script de desenvolvimento, que executa o servidor de desenvolvimento local para nós. Aqui, é chamado de início. Bem, geralmente é chamado de início, mas faz exatamente o mesmo. Ele lança o servidor de desenvolvimento local. Em seguida, temos o script de construção, novamente, para criar uma compilação de produção, script de teste que executa testes. Vamos tocar isso em um segundo e ejetar. O Eject nos permite cancelar a configuração dos scripts do React e personalizar a configuração nós mesmos na medida em que precisarmos. Então, temos muitas dependências relacionadas à caixa de trabalho. O que é isso? Tudo isso está relacionado à criação de um aplicativo web progressivo. Vamos falar sobre isso mais tarde, não tocaremos em nada disso. Sinais vitais da web, vamos abordar isso em um segundo. Os scripts React são o pacote com a configuração. Dependência do React e biblioteca de testes, também abordaremos isso em um segundo, e nossas dependências de desenvolvimento que acabamos de instalar. Incrível, agora, se olharmos dentro da pasta pública, o propósito dessa pasta é exatamente o mesmo do feed. Quaisquer arquivos que colocamos aqui são mapeados para o segmento de URL em nosso aplicativo. Aqui temos o índice HTML dentro da pasta pública. Se no feed o tínhamos na pasta raiz, aqui o temos em público. Essa é a primeira, digamos, grande diferença entre o feed e o aplicativo Create React. Aqui temos algumas coisas que são diferentes. Primeiro, temos esse URL público, variável global, esse URL público será enviado pelo webpack. Quando nosso aplicativo for compilado, webpack processará o HTML do índice e substituirá esse URL público pelo caminho raiz do nosso aplicativo. No nosso caso, ele será traduzido para algo assim. Só favicon, e pronto. Agora também temos o elemento raiz no qual o aplicativo será montado. Praticamente o que tínhamos no tic-tac-toe. Então temos o arquivo de manifesto. O arquivo de manifesto é editado em relação algo relacionado à criação do Progressive Web App. Basicamente, ele controlará o atalho que será usado para abrir nosso aplicativo. Vamos abordar isso quando voltarmos ao Progressive Web App, não pensamos nisso agora. Agora, o que temos na pasta de origem? Na pasta de origem, temos uma configuração muito básica. Na verdade, vamos executar o script Start para iniciar o servidor de desenvolvimento. Vamos ver, o que temos aqui. Se eu voltar aqui, demoro algum tempo para abrir o aplicativo. Enquanto ainda está abrindo, vamos ver o que temos dentro do índice que ele abriu. Vamos ver a aparência do aplicativo e voltaremos aos arquivos. Você pode ver que leva alguns minutos e já temos um problema instantâneo aqui. O React é definido, mas nunca usado dentro do App.js, porque, como eu disse, no React 17 e anteriores, você sempre tinha que importar o React do react sempre que usasse o JSX dentro dos arquivos. A partir do React 18, isso não é necessário. Usamos uma opção de plug-in específica aqui jsx-runtime, que nos dirá que não precisamos dela. É por isso que o removemos. No React 18, isso não é necessário. Agora, este é o nosso aplicativo, é assim que parece agora , nada muito especial, uma configuração bem básica. Vamos explorar os arquivos. Vamos começar com o Index.js, nosso ponto de entrada, e aqui temos algumas coisas que nunca vimos antes. Em primeiro lugar, temos ReactDOM.createRoute, documento. Obtenha elemento por ID raiz, que é o elemento que pegamos do índice HTML. As identidades devem coincidir. É aqui que o aplicativo será montado. Novamente, temos um modo estrito que renderiza nosso aplicativo com uma configuração bastante básica, mas também temos o registro do Service Worker e relatamos sinais vitais na web. O que são esses? Registro de Service Worker e Service Worker GS. Esses são os arquivos que farão nosso aplicativo web um aplicativo web progressivo. Não queremos realmente pensar neles agora. Isso é algo que usaremos mais tarde. Nós apenas os mantemos e, por enquanto, simplesmente ignoramos o que temos aqui sobre o registro de Service Worker. Novamente, falaremos sobre isso mais tarde. Mas também temos relatórios de sinais vitais da web aqui. Se olharmos para dentro, sinais vitais da web, é isso que importamos. Aqui, é apenas uma função simples que importa algo chamado web vitals e depois disso, chama um conjunto de funções aqui. O que é um web vitals que está sendo importado aqui? Este é o pacote que temos aqui. Web Vitals. Se voltarmos ao registro do NPM, dentro do registro do NPM, podemos pesquisar esse pacote onde está vital e ver o que exatamente ele faz. Resumindo, o web vitals é um pacote, é basicamente um conjunto de funções que você vê no relatório web vitals. Essas funções nos permitem medir o desempenho de nosso aplicativo. Que tipo de desempenho? O desempenho é baseado em diferentes métricas que podemos coletar quando nossa página é carregada. Você pode ler sobre eles em detalhes aqui na página oficial do pacote do NPM. É muito útil quando você deseja obter a máxima otimização e velocidade máxima em seu aplicativo. Como funciona, é que dentro do índice, sim, chamamos esse relatório de web vitals e aqui como um retorno de chamada, que é definido novamente aqui na entrada de desempenho aqui. O retorno de chamada que passamos aqui será chamado em cada métrica. Se passarmos, cancele aqui. Isso significa que todas as nossas métricas de desempenho serão canceladas. Deixe-me realmente salvá-lo e ver o que exatamente eu preciso. Se eu voltar para o aplicativo, vou para Inspecionar. Se eu olhar dentro do console, posso ver métricas diferentes aqui. Console registrado como objetos com valores diferentes. É exatamente isso que o pacote web vitals faz. Ele mede o desempenho e fornece métricas. Nada mais do que isso. Nós realmente não precisamos disso. Talvez, mas vamos usá-lo mais tarde, mas não agora. Portanto, podemos mantê-la como uma função simples aqui. Vamos ver o interior do App.js. Na verdade, uma boa pergunta aqui seria por que temos todos os arquivos extensão with.js em vez de JSX? Porque no Tic-Tac-Toe, em todos os lugares usamos.jsx. Bem, o Vite exigiu que usássemos a extensão.jsx e o Vite funciona de forma a pegar todos os arquivos com extensão JSX e entender que isso é o React. Aqui, como o Create React App é voltado apenas para aplicativos React, isso não é um requisito porque ele entende que tudo será React. Mas no Vite, era diferente, pois o Vite também pode ser usado para outras bibliotecas. Também vamos nomear nossos arquivos como extensão with.js. Vamos renomeá-los no próximo vídeo. No momento, não excluiremos nada daqui. Dentro do App.js, temos o arquivo de logotipo importado aqui. Eu só quero fazer uma anotação rápida aqui porque podemos fazer com que nossos ativos estáticos, como imagens, fontes, algo que é estático e não requer nenhum processamento, não requer nenhum processamento, sejam colocados em público e depois referenciados a partir do código-fonte. Mas aqui é importado. arquivo SVG é uma imagem. Ele foi importado como se fosse algum script ou módulo. Então, tudo o que é importante aqui é passado como fonte. Se olharmos para HTML, desculpe, aqui temos uma imagem que aponta para o URL. Você pode ver que é como se fosse gerado automaticamente ou algo foi feito com esse URL. Exatamente. Nos bastidores, o que o Webpack fez, para que o pacote React escrevesse a configuração, ele entendeu que queremos importar a imagem. Em seguida, ele processou a imagem e gerou automaticamente o URL para ela. Então, basicamente, foi processado pelo Bundler. Você pode ter uma pergunta sobre o porquê. Por que precisamos mantê-lo separado? Por que alguns arquivos, algumas imagens importamos da fonte e outras que mantemos em público? Na verdade, não há nenhuma razão especial por trás disso, eu suponho. A diferença é que esses arquivos são processados pelo Bundler. Esses que estão dentro da pasta pública não são processados pelo Bundler. Poderíamos ter movido esse logo.svg para o Public. Então, dentro do App.js, nós apenas referenciaríamos logo.svg, certo? Se eu salvá-lo, eu atualizo, tudo permanece o mesmo e você pode ver logo.svg é servido na rota do aplicativo porque o temos dentro da pasta pública e os segmentos de URL são mapeados, como você lembra. Ele é colocado dentro da fonte, depois é importado desse jeito e, em seguida, na fonte especificada. Dessa forma, você pode carregar imagens. Diz que isso não pode ser resolvido. Provavelmente, isso ocorre porque eu preciso reiniciar meu aplicativo para que ele possa realmente retomá-lo. Vamos fazer isso por precaução para garantir. Mas acho que isso é tudo o que precisávamos fazer. O que podemos fazer aqui para resumir isso, o que acabamos de criar até agora, precisamos também no Git fazer o upload desse projeto que acabamos de criar no GitHub e adicionar outro commit porque instalamos novas dependências. Vou iniciar o aplicativo. Você pode ver que estava funcionando bem e o URL foi bem-sucedido. De qualquer forma, você pode ver que o Git já está nele aqui. Quando criei o modelo, quando executo o npx Create React App, ele inicializou automaticamente o Git dentro dessa pasta. Se eu digitar git log, já tenho um commit inicial aqui. O comando cuidou disso. No entanto, como introduzimos nossas próprias mudanças, vamos confirmá-las. Vamos ver o que temos aqui? Temos App.js, index.js. Vou remover todas as alterações que fizemos aqui porque realmente não precisamos delas. Vamos fazer tudo no próximo vídeo. Estamos interessados apenas em nossa configuração ESLint que adicionamos e na configuração Prettier, na qual adicionamos package lock e package.json porque instalamos as dependências de desenvolvimento. Ótimo. Tudo está dentro do palco. Vou apenas confirmar tudo e chamá-lo de Prettier e ESLint instalado e configurado. Incrível. Agora é hora de enviarmos esse projeto para o GitHub. Vamos embora. Na minha conta do GitHub, vou criar um novo repositório no canto superior direito. nome do meu repositório será Box Office App. Vou torná-lo privado. Não quero adicionar nenhum Read Me. Eu já tenho gitignore. Se olharmos dentro do gitignore, assim como antes, temos os módulos do node a pasta Build ignorada. Se no Tic-Tac-Toe, tivemos uma compilação gerada dentro da pasta do disco, Create React App gera uma compilação dentro da pasta Build. Na verdade, vamos criar o repositório e depois executar o comando build. Em seguida, faremos o upload de tudo. Eu clico em Criar repositório. Então, novamente, siga exatamente o mesmo procedimento. Eu copio git remote add origin na URL do meu repositório. Eu o coloco dentro do meu terminal, eu executo esse comando. Então eu faço git remote minus v para verificar se a origem do alias aponta para o meu repositório do GitHub. Incrível. Então eu vou fazer git push origin master. E agora, se eu atualizar meu repositório do GitHub, ele estará lá. Incrível. Vamos tentar executar o script de construção no final só para ver se ele realmente funciona. Npm execute a compilação conforme definido em package.json. Onde estão nossos roteiros? Aqui, e vamos ver, diz criar uma versão otimizada de produção. Bem, temos o React definido, mas nunca usado. Isso é exatamente o que tínhamos, na verdade. É muito irritante que nenhum vars não utilizado produza um erro. Porque você pode ver que isso interrompe a construção porque o ESLint produz um erro para nenhum vars não utilizado. Vamos prosseguir e, especificamente para essa regra, se eu não estiver errado, fizemos exatamente a mesma coisa no Tic-Tac-Toe para não usar carros não utilizados. Vamos contar, por favor, avise-nos em vez de um erro. Um aviso, é só um aviso. É só uma mensagem para avisá-lo. Isso não quebra a construção nem nada. Você pode ver que agora ele ficou amarelo e minha construção foi concluída com sucesso. Vou apenas manter como está, não vou modificar o App.js. Deixe-me remover as alterações que fiz. Aqui você pode ver a pasta Build apareceu e, se olharmos para o terminal, temos a saída de que o projeto foi construído, supondo que ele esteja hospedado na rota e depois em um conjunto diferente de comandos, e se olharmos dentro da compilação, podemos ver que esta é nossa compilação de produção. Temos apenas arquivos estáticos. Temos HTML, CSS, JavaScript, imagens e arquivos Json e até TXT. Temos licença para um prestador de serviços. Agora, pegaremos a pasta Build e a enviaremos para hospedá-la. Novamente, isso é o que vamos fazer no final. Você pode ver isso funcionar. Parece perfeito, não é? Agora, vamos adicionar essa alteração do ESLint ao Git. Então, vou confirmar e dar um nome, transformar nenhum vars não utilizado em aviso e, em seguida, fazer o upload de tudo para o GitHub. Ótimo. No próximo vídeo, vamos limpar todos esses arquivos dentro do código-fonte. Depois disso, vamos começar com o desenvolvimento. Nos vemos lá. 59. 03 Limpeza de arquivos redunant: Olá. No último vídeo, criamos um novo projeto usando o modelo de aplicativo Create React. Neste vídeo, vamos apenas fazer uma pequena limpeza, que removerá esses arquivos desnecessários que não vamos usar da fonte. Nesse exato momento, começaremos o desenvolvimento. Vamos embora. Em primeiro lugar, no último vídeo, eu realmente não abordei nada sobre testes de configuração e os pacotes de bibliotecas de teste que temos aqui. Portanto, podemos realmente testar aplicativos React. Podemos escrever testes programáticos usando algo chamado biblioteca de testes React. Não vamos fazer isso aqui na bilheteria. É por isso que simplesmente o removemos porque não será usado. A primeira coisa que farei é remover “App.test.js”. Vou remover “Setup.tests.js” de “package.json”. Vou remover todas essas dependências desse jeito. Vamos ver, e pronto. Agora removemos a biblioteca de testes do projeto porque não vamos abordá-la aqui. Em seguida, temos “logo.svg”. Nós realmente não precisamos disso. Temos "index.css “, podemos realmente mantê-lo. Temos "App.css “, nós realmente não precisamos dele porque" index.css " contém estilos globais para o corpo, vamos mantê-lo lá e não tocá-lo. Então temos “reportWebvitals.js”. Talvez precisemos dele para medir o desempenho se estivermos realmente interessados, então podemos mantê-lo, por precaução. "Service-worker.js" é algo que podemos anexar posteriormente, quando vamos lidar com aplicativos web progressivos. E, a propósito, se você olhar para dentro do prestador de serviços, já podemos ver que temos algo aqui destacado em vermelho. Novamente, são nossas adoráveis regras de ESLint. O que podemos fazer sobre isso é simplesmente desativar o ESLint somente nesses dois arquivos, dentro de "service-worker.js" e dentro de “serviceWorkerRegistration.js”. Novamente, falaremos sobre esses arquivos mais tarde. Só queremos ter certeza de que esses arquivos não produzam nenhum erro ou aviso por parte do ESLint. Vamos usar o eslint-disable assim com uma barra em asterix, para desativar o ESLint somente para esse arquivo. Vou copiar essa linha e colá-la dentro "serviceWorkerRegistration.js" na parte superior. Agora não temos nenhum aviso ou erro de ESLint aqui. Incrível. A próxima coisa que faremos é renomear "index.js" e " App.js " para ter a extensão.jsx apenas para diferenciar arquivos com marcação jsx e arquivos sem marcação jsx, apenas arquivos js comuns. Isso é especificamente importante para "service-worker.js" e "erviceWorkerRegistration.js”. Porque esses arquivos não são nada sobre o React. Esses são arquivos apenas sobre front-end. Eles não podem ser usados especificamente no React. Nós renomeamos "index.js" para ter a marcação.jsx. Exatamente o mesmo, faremos para "App.js”. Dentro do App.jsx, não precisamos importar o React do React porque, novamente, usamos o React 18. E o React 18 não exige que você importe o React para o escopo do jsx. Removemos "logo.svg “, então removemos a referência a um arquivo inexistente. Removemos "app.css “, removemos novamente a referência a um arquivo existente. Dentro do componente App, podemos simplesmente manter olá por enquanto, sem nenhum nome de classe aqui. Muito simples. É muito simples aqui também. "Index.css" é mantido, por isso que importamos. Vamos ver o que mais aqui também. O que quer que tenhamos em público no final, vamos substituí-lo por nossos próprios ícones, por nossas próprias imagens. Não os excluímos por enquanto, e acho que é basicamente isso. A única coisa que precisamos fazer executar o npm install para refletir as mudanças que fizemos em “package.json”. Como removemos essas dependências da biblioteca de teste aqui, elas são removidas de “package.json”, mas não são desinstaladas de “node_modules”. Se eu executar o npm install, ele apenas removerá as dependências inexistentes e “package.json” da pasta “node_modules”. Você pode ver: “Foram removidos 71 pacotes”. Novamente, tenho seis altas vulnerabilidades. Por favor, não me assuste com eles. Por enquanto, vamos nos comprometer, git add. Já está em estágio e o “git commit” será removido ou limpo da pasta de origem do aplicativo Create React inicial. configuração. Incrível. Nós nos esforçamos para dominar tudo e, nessa boa nota, nos vemos no próximo vídeo. 60. 04 React Router v6: Ei, neste vídeo, finalmente prosseguiremos com a codificação e, finalmente, começaremos a construir algo. Vamos embora. Se você se lembra de Tic-Tac-Toe, tínhamos apenas uma página em nosso aplicativo. Não tínhamos nenhuma navegação entre as páginas, e o fato é que, no React, não há navegação embutida na biblioteca. Isso significa que, se quisermos fazer alguma navegação entre as páginas, precisamos fazer isso sozinhos. Bem, há um pacote para isso, que gerencia a navegação para nós. Na realidade, existem vários pacotes que podem fornecer roteamento dentro do aplicativo. Essa navegação entre páginas é chamada de roteamento entre páginas. Existem pacotes diferentes que podem fazer isso, eles têm mais ou menos a mesma interface. O que vamos usar é o React Router. Se eu abrir a documentação oficial aqui, posso escolher que sou novo. No entanto, posso concordar que sua documentação mais recente não é muito clara. Não vi nada que eu precisasse executar para instalar o React Router e esse tutorial também é muito longo e abrange tudo, mas e se eu quiser começar rapidamente? Para começar com o React Router, primeiro precisamos instalar esse pacote e, para fazer isso, precisamos executar npm install react-router-dom. Fazemos isso, depois disso, ele aparecerá dentro do pacote json. Agora, vou executar o servidor de desenvolvimento novamente e vamos dar uma olhada na documentação. Aqui, se passarmos pela configuração, ela realmente nos solicitará a inicialização de um novo aplicativo React com o Vite. Vamos pular essa etapa. Depois disso, vemos “Adicionar um roteador” e aqui precisamos criar algo assim. Mas eu pessoalmente acho um pouco confuso seguir esta documentação, porque eu conheço o React Router das versões anteriores, então atualmente ele está na versão 6 e todas as versões principais, como 5, 4, 3, ele sempre muda sua API, sua interface, porque agora é completamente diferente do que era antes. Para simplificar, vamos para os conceitos principais à esquerda e aqui vamos para a seção chamada Renderização, se eu não estiver errado. Aqui, você pode encontrar um exemplo muito bom do qual fica claro o que exatamente o React Router faz e o que vamos fazer? Em vez de seguir toda essa longa documentação, vamos pegar apenas o que precisamos. Vamos pegar esse exemplo e entender o que exatamente o React Router pode nos dar. Podemos ver uma chamada raiz de criação bem básica que já temos dentro index.jsx e vemos que precisamos ter essa árvore de classificação. Em primeiro lugar, precisamos ter um roteador de navegador. Vamos importar isso e provavelmente faremos tudo isso dentro do App. Na verdade, podemos importar roteador do navegador e usá-lo dentro do index.jsx, no entanto, vamos fazer isso dentro do App. Primeiro precisamos obter de algum lugar todos esses componentes, todos eles são importados do react-router-dom e há algum lugar dentro dessa longa documentação. Você pode realmente encontrá-los lá. Precisamos de um roteador de navegador e precisamos de rotas, e precisamos de rotas. Então, vamos importar algo do react-router-dom, então precisamos pegar o roteador do navegador e precisamos pegar rotas, não o roteador, e precisamos pegar a rota. Esses três componentes. Agora, o que vou fazer copiar essa marcação e colocá-la dentro do App, sem mais nem menos. Mas aqui, agora não temos todos esses componentes definidos aqui, tudo bem. Na verdade, o que está acontecendo aqui? Usando essa estrutura em forma de árvore, podemos definir rotas em nosso aplicativo React. Pense nas rotas como se fossem páginas, então cada rota é representada por uma página. A rota é basicamente apenas um segmento de URL. Se você tiver, digamos que para equipes de caminho, sempre que o URL for, digamos, equipes de corte, podemos exibir esse componente de equipes usando a sintaxe. Mas não vamos fazer isso. Por enquanto, só precisamos mostrar pelo menos alguma coisa. Vamos comentar isso, esses componentes de rotas e, analisando-os, vamos ver o que podemos fazer para nós mesmos. Vamos apenas seguir em frente e criar rota no caminho; rota e índice. Um elemento será alguma coisa. O que precisamos mostrar aqui? Aqui, precisamos renderizar o componente que representará nossa página. O que eu sugiro é que, dentro do Source, criemos uma nova pasta e a chamemos de Pages, e aqui vamos criar componentes que representem nossas páginas. Vou criar um novo arquivo aqui, vamos chamá-lo de Home.jsx. A partir daqui, vou criar um componente doméstico como esse e depois exportá-lo por padrão desta forma. A partir de agora, será uma div simples que diz Página inicial. Então, para o índice de caminho apenas para rota, vamos renderizar o componente inicial e, a propósito, você pode ver assim que eu digito home e quando meu cursor é colocado no final, eu tenho esse IntelliSense aqui no menu suspenso. Se eu pressionar “Tab”, ele será importado para mim, muito legal, não é? Agora, eu mantenho assim e, se eu voltar ao meu aplicativo, veja o que eu tenho. Eu tenho uma página inicial aqui e, se eu acessar qualquer outro URL, tenho uma página vazia. Se eu inspecionar a marcação, abro o corpo, tenho a rota. Mas dentro da rota, eu não tenho nada. Isso porque aqui, eu não defini nenhuma rota, nenhuma página. React Router funciona da forma que combina o segmento de URL aqui, o nome do caminho com o caminho que você especifica aqui nas renderizações, elemento correspondente. Agora, vamos tentar criar outra página. Vamos chamá-lo de Contato e aqui vamos apenas renderizar. Só para dar um exemplo, vou criar div e dizer contato. Agora, se eu entrar em contato, vejo a marcação, o que eu passei como elemento aqui, sem mais nem menos. Agora sabemos como o React Router funciona. O resto que você vê aqui no exemplo, abordaremos isso nos próximos vídeos, porque isso é algo sobre layout, então podemos ter um layout que pode ser compartilhado entre várias páginas. É aí que entra essa rota sem nenhum caminho ou sem nenhum índice. Além disso, abordaremos esta coluna aqui, que será a representação de uma página dinâmica, mas, novamente, vamos abordá-la mais tarde. Esse não é o momento. O que faremos por enquanto, talvez apenas criaremos nossas páginas iniciais. O que posso dizer aqui é que na bilheteria teremos a página inicial e, em seguida, teremos a página favorita. Para referência futura, como já criamos duas páginas, vamos adicionar outro componente de página, que chamaremos de básico de início, e vou copiar tudo o que tenho dentro. Vou renomeá-lo para estrelado. Então, dentro do componente do aplicativo, novamente, vou importar o componente favorito, que representa nossa página. Em vez de contato, vou exibir o caminho com estrela e, em vez de contato , o caminho com estrela apenas para verificar se, se eu for para favorito, tenho minha página favorita. Ótimo. E essas páginas vazias , então, se seguirmos por uma rota indefinida? Não é 404, mas é uma página que não foi encontrada. React Router tem uma explicação para isso, como lidar com isso. Se formos para a seção de perguntas frequentes aqui, podemos ver como adiciono uma rota 404 sem correspondência no React Router 6. Você pode simplesmente usar isso. Vamos colocá-lo talvez no final ou no topo. Se não me engano, ele pode ser colocado em qualquer lugar. Em vez de nenhuma correspondência importante por enquanto ou talvez não a alteremos, vamos apenas exibir não encontrada. Vamos tentar. Nós acessamos o aplicativo e sempre que vamos para qualquer rota que não definimos, recebemos não encontrada. Mas se formos para a página inicial, teremos a página inicial, se formos para estrelar, teremos estrelado. Incrível. Agora, como podemos navegar entre essas páginas porque temos tags âncora, mas não podemos realmente usar tags âncora quando usamos uma biblioteca de roteamento do lado do cliente, como o React Router. Precisamos usar um componente específico para isso. Vamos para casa e agora precisamos de algo chamado componente link, que importamos novamente do componente de link dom do React Router. Vou apenas exibir um componente de link assim, é basicamente apenas um invólucro em torno da tag âncora, mas é específico do React Router então o React Router pode entender que você queria fazer a transição de uma rota para outra rota e, em seguida, vamos chamá-la de go para a página favorita. Para esse componente de link, precisamos passar prop called para especificar a rota que gostaríamos seguir quando clicarmos nesse link. Como nosso componente favorito é definido em caminho marcado com estrela, quando clicamos em Ir para a página favorita, vamos para a rota favorita. Agora voltamos para casa, se olharmos a marcação, você pode ver que, por baixo do capô, é na verdade uma etiqueta de ancoragem que leva à rota marcada com estrelas. Se clicarmos nela, agora estamos na página favorita. Legal, não é? É isso. Bem, esses são, na verdade, os princípios básicos do React Router. Como você pode ver, seu objetivo é oferecer essa experiência de navegação no aplicativo React. Porque, novamente, o React não tem nenhuma solução embutida para isso, é por isso que precisamos usar nossa própria solução ou instalar uma biblioteca que forneça recursos de roteamento para nós. Acho que é isso para a introdução sobre o React Router. No próximo vídeo, começaremos a criar layouts e continuaremos com nosso aplicativo. No final, eu só queria adicionar uma nota sobre o React Router, e por que realmente os chamamos de rotas, por que não os chamamos de páginas? O fato é que estamos criando algo chamado aplicativo de página única. Um aplicativo de página única é basicamente um único arquivo HTML de índice aqui, por isso é chamado de aplicativo de página única. Sempre que navegamos entre rotas ou as chamamos de páginas, o que realmente acontece é que o React Router usa JavaScript para substituir a marcação HTML e, em seguida, exibir os componentes correspondentes, chamamos isso de navegação, mas basicamente o que ele faz, ele apenas pega o HTML existente, o remove e insere um novo HTML e, em seguida, substitui o URL por qualquer coisa que especifique como rota. Tudo aqui é gerenciado por JavaScript. Ainda temos a mesma página, não muda que o HTML não mude aqui, o esqueleto, o modelo, essa indexação não mude, mas o JavaScript realmente imita essa experiência de navegação, então, para o usuário final que consome o aplicativo, parece que estamos navegando nas páginas. Bem, podemos dizer que de fato somos. Tecnicamente falando, isso é apenas remover HTML e inserir um novo HTML na página e alterar o segmento de URL, só isso. Nos aplicativos tradicionais, quando você clica em uma página diferente, a página é atualizada, e é quando você tem uma navegação real, digamos, de página para página. Aqui, no que chamamos de navegação do lado do cliente, a navegação do lado do cliente significa que, na verdade, navegamos pelas páginas usando JavaScript. Agora, vamos confirmar as mudanças que fizemos. Dentro do aplicativo, talvez eu o mantenha. Vamos guardá-lo para referência futura. Vamos adicionar jsx, vamos adicionar home, vamos adicionar tudo ao estágio, instalamos o React Router e, eventualmente, vamos confirmar tudo e dizer Edit, React Router dom no aplicativo ou talvez tenha instalado o React Router dom. Perfeito. Nos vemos na próxima. 61. 05 Layouts e navegação entre páginas: Olá de novo. Neste vídeo, falaremos sobre layouts, como podemos gerenciá-los e quais são os layouts em primeiro lugar. No último vídeo, instalamos e digamos, configuramos o roteador de reação. Essa é a solução de roteamento que usaremos para nosso aplicativo. Agora, veremos como podemos realmente aplicar layouts porque temos uma página de índice, e digamos que elas compartilhem um layout comum. Nas duas páginas, queremos ver a navegação. O que podemos realmente fazer ir até um componente doméstico e colocar o link aqui. Então vamos para o componente estrelado e colocamos o link aqui, mas isso é muita repetição. Só queremos ter uma marcação comum que coloquemos em um só lugar e que seja exibida em todos os lugares. Olhando para este exemplo, se voltarmos à documentação, se formos para Conceitos principais, renderização, este é o lugar onde tiramos essa marcação do último vídeo. Podemos ver algo chamado Layout Routes. Se você ler aqui, ele diz basicamente que esse elemento de rota aqui que envolve outras rotas é apenas um componente que pode fornecer algum layout para as rotas subjacentes. Ela não representa a página em si. Os pagers são representados apenas por rotas que definem o caminho prop aqui. Para obter o layout, podemos seguir essa abordagem. Se precisarmos compartilhar o layout entre a página inicial e a página com estrela, podemos agrupá-las na rota, como aqui. Então, vamos em frente. Vamos criar um componente de rota. Vamos agrupar a página inicial e a página com estrela nesse caminho. Podemos especificar um único elemento sem nenhum suporte de caminho. Aqui, estará nosso layout que gostaríamos de ver para essas páginas. Como vamos gerenciar isso? Dentro das classificações, criaríamos uma nova pasta e a chamaríamos de componentes. Aqui, vamos colocar um novo componente, que chamaremos MainPageLayout ou vamos chamá-lo de MainLayout. Aqui, vou criar o layout principal. Em seguida, exporte-o daqui, exporte o padrão, MainLayout. Incrível. Agora, vamos importar esse layout dos componentes, MainLayout. Então, em vez do layout da página, vamos usar o layout da página principal. No entanto, como exatamente isso funciona? Porque se eu abrir meu layout principal, ele ficará completamente vazio. Não há nada lá dentro. Então, o que será renderizado? Vamos tentar ver. Se voltarmos ao aplicativo, agora, nosso aplicativo está vazio. Bem, o que acontece? O fato é que, se você se lembra, no React, temos algo chamado adereço infantil. Se definirmos um componente e digamos algo assim, MainLayout e por dentro passarmos algo, o que MainLayout e por dentro passarmos algo, quer que passemos dentro desse componente entre o colchete de abertura e fechamento, ele ficará disponível como o suporte infantil que podemos usar dentro da marcação JSX dentro desse componente. No entanto, com o roteador React, não parece assim. Não passamos por nenhuma criança porque passamos como um componente de fechamento automático. Então, como isso funciona? Se olharmos aqui dentro do PageLayout, precisamos de algo chamado outlet. Aqui à direita, está a seção chamada tomada. O Outlet é usado dentro desses componentes que representam layouts. Eles representam basicamente as crianças, pelo menos, o conceito é muito parecido com o de crianças. Eu passo por esse conjunto de rotas. Esse elemento tem o layout principal. Mas, como não temos acesso a crianças aqui, ainda precisamos informar esse componente MainLayout que queremos renderizar o que quer que esteja dentro. Para isso, o roteador React tem esse componente chamado outlet. O Outlet é basicamente como crianças, mas para todas as rotas que são passadas dentro desse componente de rota. Bem, é confuso. Na verdade, deixe-me mostrar a você. Importamos algo da reação para dom e esse algo vai sair. Em vez de escrever para crianças, tomada é a substituta. Não usamos crianças, usamos apenas tomadas. Simples assim. Aqui em cima de nossa loja, vamos dizer que isso é marcação compartilhada. Eu o guardo. Eu volto e você pode ver que o que está sendo renderizado aqui é que esta é uma marcação compartilhada e, em seguida, esta é uma página com estrela. Basicamente, a saída aqui representa tudo o que passamos dentro desse layout , conforme definido pelos componentes da rota. Agora, se formos para casa, veremos exatamente a mesma imagem. Temos isso como marcação compartilhada. Agora, vamos adicionar uma navegação que será compartilhada entre as páginas. Dentro dos componentes, vou criar um novo componente, que chamarei de Navs. Por enquanto, novamente, como sempre, será div, que diz algo e depois exportará por padrão Navs. Ótimo. Então, dentro de main, em vez disso, está a marcação compartilhada, vamos exibir o componente Navs. Novamente, você pode ver que comecei a digitar, meu cursor está no final. Eu tenho o menu suspenso com a inteligência e se eu pressionar “Tab”, agora, boom, ela é importada automaticamente. No entanto, tenha cuidado com isso. Esse é um recurso muito importante, eu diria que ele pode importar facilmente os outros arquivos, não exatamente o que você espera. Tenha cuidado com isso e sempre verifique suas entradas. Estamos sob o comando da Marinha aqui. Dentro do Navs, gostaríamos de exibir a navegação. Vamos pegar aquele trecho de código que já temos na página inicial. O componente de link, você lembra que usamos para navegar entre as páginas quando usamos a biblioteca do lado do cliente react-router-dom. Vou copiar o link de importação do react-router-dom. Vou colocá-lo dentro de Navs. Aqui, precisamos exibir a navegação. Como vamos fazer isso? Antes de tudo, precisamos definir nossos botões nos quais vamos clicar e fazer a transição entre as páginas. Vamos definir nossa matriz de botões, matriz de elementos, que serão nossos links. Em seguida, mapearemos esses links para a marcação JSX exatamente da mesma forma que fizemos com a história no tic-tac-toe. Aqui fora do Navs, vou criar um componente porque conhecemos um componente, apenas uma variável chamada links. Será uma matriz de objetos e cada objeto terá a seguinte forma. Ele terá texto e precisará. Para será algo que passaremos para o componente do link e o texto será o texto exibido. O texto vai chegar em casa. Ele irá para a rota, para a página inicial. Em seguida, vamos adicionar outro objeto aqui. Vamos chamá-lo de Starred. Isso nos levará à rota estrelada. Agora, precisamos pegar essa matriz e marcá-la com a marcação JSX. Então, aqui, dentro do Navs, em vez de div, podemos exibir elementos do UL, ou talvez dentro do div , vamos exibir o UL, vamos continuar assim. Agora, dentro dessa UL, vamos mapear nossos links. Então, vou abrir colchetes aqui. Eu vou dizer ao Links.map. Agora pegamos o item. Vamos nomear esse objeto que mapeamos como item. Vamos mapeá-lo para o elemento li. Dentro desse elemento li, vamos dizer que , por favor, exiba item.text e, como uma chave, porque você se lembra que quando mapeamos elementos sempre para a marcação JSX até o elemento de encapsulamento, sempre para a marcação JSX até o elemento de encapsulamento, precisamos passar uma chave exclusiva que identificará esse elemento dentro da marcação JSX que está sendo mapeada. Portanto, em nosso caso, o segmento de URL que usamos aqui é exclusivo para cada item ou pode ser texto. Mas vamos passar para a chave. item to identificará nosso elemento. Também precisamos transformá-lo em um link. Usamos o componente link para isso, que importamos do react-router-dom. Então, em vez do texto do item, vamos fazer o texto do item do link. Para o adereço da fila dentro do oponente do link, vamos passar item.to. Vai ficar assim. Agora, voltamos ao aplicativo e o que vemos, vemos a navegação. Se clicarmos em Favoritos, vamos para a página Favoritos. Se clicarmos em Início, vamos para Início. Legal, não é? Parabéns, agora temos o componente de navegação, que funciona muito bem, assim como usamos layouts para gerenciar isso. Agora, vamos limpar a página inicial e eliminar link aqui e apenas dizer Início. Agora, parece que sim. Incrível, não é? Talvez, vamos continuar aqui e adicionar um título. Vamos criar um novo componente aqui e chamá-lo de Título ou, digamos, AppTitle. Então, a partir daqui, vamos adotar outra abordagem, porque sempre estávamos criando uma função e depois a exportando por padrão. Então, em vez disso, podemos apenas dizer export default e, em seguida, a função e o que ela diz, vamos ver que falta o nome de exibição da definição do componente, é claro. Então, o que ele quer que façamos, ele quer que façamos algo assim. Função AppTitle. Porque ele quer que exportemos uma função que realmente tenha nome, não apenas uma função anônima como essa, mas com o nome. Isso é bom. Isso tornará o código um pouco mais declarativo. Às vezes, ajuda a rastrear erros que podem vir de diferentes funções. No nosso caso, esse não será o caso. Mesmo assim, vamos explorar mais a sintaxe do JavaScript. Vamos chamá-lo assim. Então, aqui, em vez de Navs e outlet, podemos exibir o título h1. Então, o título será o adereço que receberemos. Novamente, como começamos a explorar mais a sintaxe de JavaScript, em vez de desestruturar, vamos aplicar a desestruturação em outro lugar. Então, recebemos o objeto de adereços. Aqui, na próxima linha, vamos aplicar a desestruturação, em vez de incorporá-la diretamente nos argumentos. Então, vamos pegar o título, assim como vamos pegar a legenda. A legenda estará dentro do parágrafo, do subtítulo, e vamos usar esse AppTitleComponent dentro do layout principal, logo abaixo dos navs. AppTitle, novamente, IntelliSense e tab, e boom, ele é importado. Vamos ver como fica. Não vejo nada ou perdi alguma coisa? Deixe-me ver. Não, eu não fiz isso. Na verdade, eu fiz. Se eu inspecionar a marcação, posso ver que tenho minha marcação, mas ela está vazia. Bem, o que acontece lá? Porque, bem, você deve ter notado, mas eu executei o AppTitle sem que nenhum adereço fosse passado. No entanto, AppTitle renderiza título e subtítulo. Como não os ultrapassamos, eles estão vazios. Isso significa que eles são indefinidos. O título está indefinido, o subtítulo é indefinido porque, novamente, não os passamos. Nesse caso, precisamos transmiti-los, olá e outra coisa. Boom, agora está aqui, foi exibido, tudo funciona. Mas aqui está uma alternativa. Digamos que temos situações em que não passamos adereços, apenas por algum motivo. Talvez tenhamos esse componente que tenha sido reutilizado em vários lugares, muitas vezes, seja o que for, e nem sempre que passamos adereços. Por esse motivo, como os componentes são apenas funções e sabemos que podemos aplicar argumentos padrão às funções, podemos fazer exatamente o mesmo aqui em Componentes. Portanto, a partir do objeto props, o objeto props é sempre definido, ele está pelo menos vazio. Desse objeto, distraímos seu título, subtítulo que não está definido nesse objeto porque não passamos adereços. Mas podemos aplicar valores padrão para eles. Se não passarmos nenhum título por padrão, será Bilheteria e Legenda, aplicativo de pesquisa de filmes ou talvez, digamos assim, você está procurando um filme ou ator? Só uma pergunta, algo assim. Nossa estrutura final ficará assim. Se olharmos para dentro, você pode ver, bem, que eles estão sendo aplicados. Se eu voltar ao layout principal, bem, você pode ver que eu não passo nada, mas ainda tenho meus valores padrão. Se eu quiser alterá-lo ou sobrescrevê-los, eu simplesmente os passaria imediatamente e eles funcionarão. No entanto, como os definimos aqui dentro do AppTitle por padrão, não vamos passar nada aqui para os adereços. Na verdade, vamos colocá-lo em cima dos Navs. Então, parece que sim. Incrível. Então eu acho que é isso para aquele vídeo. Na verdade, fizemos muita coisa e abordamos muitos conceitos novos. Falamos sobre layouts, como podemos gerenciar layouts que podem ser compartilhados em várias páginas. Se olharmos para dentro, usamos esse componente de saída, usamos esse componente de saída, que substitui crianças, mas para a definição de rota que temos aqui. Em seguida, também abordamos como podemos criar navegação usando o componente de link e exibi-la dentro de uma marcação compartilhada, bem como títulos e argumentos padrão, bem como valores padrão para os argumentos ou para os adereços. Parece bom até agora. Vamos comprometer tudo e terminar este vídeo com uma boa nota. Então, vou parar o aplicativo. Vou comprometer tudo com uma mensagem. Vou chamá-lo “navegação adicionada e layout compartilhado para páginas iniciais e iniciais”. Incrível. Nos vemos na próxima. 62. 06 entradas: Olá novamente. No último vídeo, gerenciamos layouts e navegação dentro do nosso aplicativo. Parece muito legal. Agora podemos navegar entre páginas diferentes. Sabemos como criar rotas. Nosso próximo passo aqui será a caixa de tags que temos na página inicial na qual inserimos algo depois clicamos no botão. Em seguida, pegamos o texto da caixa de texto e o enviamos para algum back-end, que nos devolve os dados. No entanto, antes de implementarmos tudo isso, precisamos entender como podemos gerenciar as entradas no React. Neste vídeo, vamos fazer exatamente isso. Então, vamos navegar até o componente inicial e aqui, vamos criar uma entrada simples do tipo texto. Nada chique. Se formos para Início, agora temos esse elemento vazio aqui, caixa de texto vazia. Não podemos fazer muito sobre isso. E se eu quiser obter algum valor disso? Como posso fazer isso? Porque, bem, no futuro vamos adicionar um botão aqui e quando clicarmos nesse botão, precisamos de alguma forma encapsular o valor dessa entrada. Do Tic-Tac-Toe, você sabe que precisamos usar o estado sempre que temos um valor que muda durante o período do ciclo de vida do componente. Sempre que digitamos algo na entrada, esse é o valor que muda. É por isso que, por esse motivo, vamos usar o React, usar state hook. Então, vamos em frente. Do React, assim como antes, vamos voltar novos. Então, chamamos usestate hook e, internamente, precisamos passar o valor padrão que será o valor do nosso estado inicialmente quando o componente for montado. Como será um elemento de entrada e o elemento de entrada será sempre uma string e, se não tivermos nada dentro, insira apenas livros didáticos vazios, ainda é uma string, mas vazia. É por isso que vamos passar uma string vazia aqui. A razão para isso é porque, se não especificarmos nada para usestate, apenas o chamamos assim, por padrão, valor do estado inicial será indefinido. Então, como você se lembra, usestate retorna uma matriz de exatamente dois elementos, em que o primeiro elemento é o próprio estado. Então, vamos chamar esse valor de entrada de estado. A função de atualização de estado será definido como valor de entrada. Agora, como podemos realmente ouvir essas atualizações de que digitamos algo dentro da caixa de texto? Se você se lembra, temos eventos disponíveis em cada elemento HTML. Então, eles começam com o prefixo on. Portanto, se lidarmos com entradas, precisamos usar o evento onChange. Então, para esse evento onChange, vou passar por um manipulador de eventos e vamos ver o que temos e quando esse evento é acionado. Vou criar uma função aqui , chamá-la de OnInputChange. Se você se lembrar, todos os manipuladores de eventos sempre recebem o objeto de evento como o primeiro argumento. Vou apenas registrar o objeto de evento no console e , em seguida, passarei onInputChange como manipulador de eventos onChange. Agora, sempre que digito dentro da entrada, posso ver algo sendo registrado no console cada vez e, se eu expandir esse objeto, tenho aqui a propriedade de destino na qual estamos interessados. Portanto, o alvo do evento representa o alvo desse evento. No nosso caso, esse será o próprio elemento de entrada. Se eu expandi-lo aqui, tenho a propriedade value, que representa o valor que o elemento de entrada tem por vez. É por isso que podemos continuar e registrar o destino do evento no console. Vamos primeiro considerar o destino do evento apenas para ver mais uma vez que, sempre que digitamos, destino do evento representa nosso elemento HTML de entrada. Nesse elemento HTML de entrada, temos essa propriedade de valor, que representa o valor de entrada por vez. Sempre que eu digito, você vê que agora podemos ter acesso ao valor que temos dentro da caixa de texto. Muito legal. Agora podemos usar o valor de entrada definido, estado dos dados. Nesse estado de dados, podemos passar o valor alvo do evento para definir o estado. Agora, sempre que digitamos, atualizamos o estado com o valor alvo do evento. Ótimo. Agora, como podemos realmente ver esse valor de entrada é o que escrevemos nos livros didáticos. Como você se lembra, podemos simplesmente colocá-lo aqui, registrar e verificar o console, pois a atualização de estado acionará a reentrada do componente e, quando os componentes forem alugados, o JavaScript interno é executado novamente e, a cada reentrada, veremos esse log do console. Vamos tentar. Sempre que digito, agora, posso ver que realmente home.jsx6 na linha 6. Sim, eu tenho esse log do console, o que significa que o componente entra novamente, nosso estado é atualizado de acordo com a entrada. Com essa abordagem, temos um problema. O que você vê aqui é chamado de vinculação de dados unidirecional. Portanto, nas estruturas de bibliotecas, você sempre terá esse conceito de vinculação de dados unidirecional ou vinculação bidirecional de dados. O que isso significa? Portanto, com essa abordagem, introduzimos a vinculação de dados unidirecional, ouviremos as alterações dentro da caixa de texto e atualizaremos o estado. No entanto, se atualizarmos o estado, não atualizaremos o valor da entrada. Vamos tentar ver o que quero dizer. Então, se quisermos mostrar esse valor de entrada em algum lugar da página, podemos simplesmente usar a interpolação. Simples assim. Nós já sabemos o que fazer. Temos o valor de entrada aqui. Vamos ver se funciona. Sempre que eu digito, está sendo interpolado em J6 e exibido. Muito legal. Como podemos verificar se é uma vinculação de dados unidirecional? Vou criar um botão aqui com o botão “Tipo”, atualizar para aleatório. Para desclicar, vou dizer, defina o valor de entrada como algo como meu nome. Vamos ver o que temos. Então, sempre que eu digito, meu estado é atualizado, mas se eu clicar em “Atualizar para atualizações de estado aleatórias”, no entanto, o texto dentro da entrada não será atualizado. Então, o que acontece aqui exatamente? O problema é que, até termos uma vinculação de dados unidirecional, vinculamos as alterações as alterações que fazemos nos livros didáticos ao estado, mas não vinculamos o estado à caixa de texto, à entrada. Para corrigir isso, precisamos passar um atributo de valor para o elemento de entrada para que qualquer valor dentro do estado que tenhamos, ele seja mapeado e vinculado ao valor da caixa de texto. Então, para o atributo de valor, vou passar o valor de entrada. Vamos ver se eu digito algo aqui e depois clico em “Atualizar aleatoriamente”, agora o texto foi atualizado não só aqui, mas também foi atualizado dentro do elemento de entrada. Porque agora temos vinculação bidirecional de dados. Se atualizarmos o estado, ele atualizará a caixa de texto e, se atualizarmos a caixa de texto, atualizará o estado. É bidirecional, funciona em duas direções, ao contrário do que tínhamos feito anteriormente. Se avançarmos na mudança e mantivermos apenas valor aqui, será o mesmo. Será uma vinculação de dados unidirecional. Temos esse erro aqui que diz que você forneceu uma propriedade de valor sem um manipulador onChange. Até o React diz que algo não está certo aqui. Então, como você pode ver, vinculação de dados unidirecional pode ser muito complicada. Portanto, você deve sempre se lembrar do que é melhor para você. Eu diria que, na maioria dos casos, você pode nem perceber que vinculação unidirecional de dados pode potencialmente trazer seus problemas e, na maioria dos casos, não. No entanto, a vinculação bidirecional de dados é importante e você precisa entender a diferença entre ela e saber como aproveitá-la. Até agora, neste vídeo, aprendemos como gerenciar o estado com entradas. Como podemos usá-los para mudanças no elemento de entrada e no estado da atualização. Também aprendemos o que é vinculação de dados unidirecional, o que é vinculação bidirecional de dados e qual é a diferença entre elas, e por que a vinculação de dados unidirecional pode ser complicada. É sempre melhor usar a vinculação de dados bidirecional se você não tiver certeza. Acho que é isso. Agora você sabe tudo o que precisamos no próximo vídeo. Vamos criar um botão aqui. Vamos pegar tudo o que escrevermos dentro da caixa de texto e enviá-lo para a API. Vamos ver como isso se desenrola. Nos vemos lá. 63. 07 Submissão de formulário: Ei, aí. Como você se lembra, no último vídeo, falamos sobre entradas, como podemos gerenciar entradas, como podemos vincular o valor de entrada ao estado e a diferença entre vinculação de dados bidirecional e unidirecional. Neste vídeo, enviaremos dados que gravamos dentro de uma caixa de texto para uma API e receberemos os resultados da API para que possamos exibir algo em nosso aplicativo para o usuário. No último vídeo, fizemos tudo isso dentro do Home.jsx. Na verdade, podemos mantê-lo, vamos colocar esse botão aqui, logo abaixo da entrada, logo abaixo da entrada, para que possamos digitar o texto. Já temos InputValue e temos onInputChange. Talvez possamos chamá-lo de algo como SearchString, porque será basicamente nossa string de pesquisa para resultados de pesquisa. Podemos renomear o estado para searchString, searchs-t-r e definir searchs-t-r. Não precisamos emiti-lo, valor será searchString e onChange será onSearchString ou onSearchInputChange , e vamos atualizar o SearchString. Então, para esse botão OnClick, vamos removê-lo completamente. Vamos agrupar esses dois em um formulário e, em seguida, vamos aproveitar o atributo OnSubmit do formulário. Na verdade, as formas reagem, elas funcionam de forma um pouco diferente. Em aplicativos de página única, você trabalha com formulários um pouco diferentes dos aplicativos tradicionais. Em aplicativos tradicionais, quando você clica em “Enviar” e tem um formulário, você precisa definir uma ação aqui que o levará a alguma outra página. Quando você clica em “Enviar”, ele redireciona o usuário e envia dados para outra página. Em aplicativos de página única e aplicativos web modernos, ele não é gerenciado dessa forma. Como isso é gerenciado então? No formulário, colocamos o método onSubmit, e esse método onSubmit será a função que chamaremos de onSearch. Novamente, como é um manipulador de eventos para o evento de envio, temos o objeto de evento. Vamos tentar e, por enquanto, não fazer nada, o que vai passar para OnSubmit OnSearch. Novamente, como é formulário, em vez de digitar botão, para que possamos enviar o formulário, precisamos especificar que esse botão será do tipo enviar. Quando clicamos nele, ele realmente envia o formulário e, em vez de ser atualizado aleatoriamente, ele será pesquisado. Algo parecido. Vamos tentar ver se eu digitar algo aqui e pressionar “Enter” ou se eu clicar em “Pesquisar”, deixe-me pressionar “Enter”. Você vê que o aplicativo foi atualizado? Você pode ver que a página foi atualizada. Agora eu tenho esse ponto de interrogação no topo. Isso ocorre porque não tratamos o formulário adequadamente, porque ele acha que o formulário, a ação, precisa ser tratada por alguma outra página. Ele tenta redirecionar para alguma outra página para enviar dados. No entanto, assim como uma ferramenta em aplicativos web modernos, não é assim que o formulário é tratado. Para que o onSubmit impeça a atualização da página, precisamos impedir a ação que o evento de envio realiza. Por isso, chamamos de padrão a prevenção de eventos. Ao chamar esse método, evitamos o comportamento padrão desse evento. Se eu atualizar a página, deixe-me remover o ponto de interrogação na parte superior. Agora, eu digito algo, clico em “Entrar”. Você vê que nada acontece. No nosso caso, em vez de nada acontecer, precisamos realmente enviar dados para a API. O que será a API? Como vamos gerenciar isso? onde vamos começar? Se formos adivinhar aqui, se olharmos para os recursos, você pode encontrar a API TVMaze aqui. Vamos abrir esse link. A API TVMaze é uma API pública que pode nos fornecer informações sobre diferentes filmes e atores. É totalmente gratuito, tem cota ilimitada e é público. Você pode simplesmente abrir esse URL e seguir a documentação. Está muito bem documentado, com bons exemplos e boas explicações para os endpoints que possui. O que nos interessa é na verdade, o primeiro parágrafo aqui, que diz “mostrar pesquisa”. Ele tem esse URL, e aqui está um exemplo. Vamos tentar abrir isso em uma nova guia. Como você pode ver, temos dados aqui. Nós apenas o acessamos e recebemos os dados de volta. Se você der uma olhada no URL, aqui nós fornecemos o q, parâmetro de string de consulta, e se eu o alterar para outra coisa, ele me dará resultados diferentes com base na string de pesquisa. Esse parâmetro q é basicamente a string de pesquisa. Você pode ler sobre isso na descrição do que esse endpoint faz. Vamos usar esse endpoint dentro do nosso aplicativo. Vamos voltar e colocá-lo aqui. Vou apenas comentar isso. Agora, você pode ter uma pergunta. Como enviamos uma solicitação para essa API? Bem, podemos acessá-lo no navegador, mas como podemos fazer isso dentro do aplicativo? Bem, dentro do navegador, temos uma API da web chamada Fetch. A função Fetch está disponível globalmente no ambiente do navegador, portanto, podemos usá-la dentro do JavaScript. O que o Fetch faz, ele envia uma solicitação para o URL fornecido. Podemos pegar esse URL, podemos chamar Fetch. Novamente, é uma função que envia solicitações e está disponível globalmente no JavaScript do navegador. Chamamos essa função Fetch aqui e passamos o URL para dentro. Eu clico em “Entrar” e, como você pode ver, ele nos retorna uma promessa, um objeto de promessa. Isso significa que começamos a trabalhar com JavaScript assíncrono. É aqui que as coisas começam a ficar interessantes. Para obter valor da promessa, temos que aguardar essa promessa ou resolvê-la. Por enquanto, vamos usar a sintaxe.then aqui. Essa função Fetch é resolvida para o objeto de resposta. A promessa retornada do Fetch resulta no objeto de resposta, que representa a resposta dessa solicitação. Vamos chamá-lo assim. Vou chamá-la de resposta, e vamos tentar a resposta console.log. Esse é o objeto de resposta que temos. Ela representa o status da resposta, o URL usado, os cabeçalhos e algumas coisas diferentes aqui. No entanto, esse objeto de resposta também tem o método.JSON disponível em sua resposta ao JSON. Também é um método que retorna uma promessa. A promessa é revertida para o corpo de resposta. O que você vê aqui dentro do navegador é o corpo da resposta. É basicamente o que está sendo retornado do servidor, a resposta, então a obtemos no formato JSON. É por isso que chamamos o método.JSON. Novamente, ele retorna uma promessa, que se resolve para o corpo. O que vamos fazer? Vamos agrupar vários densos aqui primeiro. Depois, chamaremos o método.JSON no objeto de resposta. Em seguida, retornamos essa promessa de.then callback, o que significa que, no próximo, ela será resolvida. Em seguida, teremos nossa carga útil ou corpo de resposta. Vamos chamá-lo de body e console.log body. Agora, essa string nos deu essa matriz de 10 elementos. Se o expandirmos, você poderá ver que esses são os dados que temos aqui dentro da janela do navegador. Legal. Mas agora gerenciamos isso programaticamente usando a API Fetch. Exatamente o mesmo, podemos fazer não apenas aqui, mas dentro do nosso código, porque o que escrevemos aqui será o JavaScript do navegador do lado do cliente e nós apenas brincamos com ele aqui diretamente dentro do navegador , mas ainda assim não importa. Isso foi apenas para dar uma visão geral de como isso vai ser. Mas vamos fazer isso aqui dentro do nosso código. Dentro do OnSearch, chamaremos essa API Fetch de tvmaze.com/search/shows. Agora, em vez de usar a sintaxe.then, podemos usar async-await para torná-la mais legível. Para usar await, se você ver eu passar o mouse sobre ele, ele diz que expressões de espera só são permitidas nas funções de sincronização , o que significa que precisamos marcar essa função como uma sincronização e agora a mensagem desaparece. Aguardamos Fetch, então obtemos uma resposta. Então temos body by await Response.json. Aqui, quando eu digito resposta e pressiono “Dot”, você pode ver que agora eu tenho o IntelliSense, que me dá o método.JSON. Se eu ligar, você pode ver a janela aparecer, que significa que ela retorna uma promessa. Agora temos o corpo. Se tentarmos cancelar o corpo do registro aqui e voltarmos ao nosso aplicativo, onde está? Aqui. Na verdade, isso não importa. Se eu digitar algo aqui, posso ver os dados aqui que vêm da linha 16 do Home.jsx, do registro do nosso console aqui, que significa que acabamos de fazer a pesquisa programaticamente. Enviamos uma solicitação. Se abrirmos a guia de rede aqui e eu clicar em “Pesquisar”, você verá que enviamos uma solicitação para o URL que especificamos no Fetch e, se visualizarmos, obteremos os dados. Incrível. Agora, vamos tornar essa solicitação dinâmica porque temos a string de pesquisa aqui, mas enviamos voz o tempo todo. Declaramos aqui SearchString, para que possamos passá-lo para o Fetch substituindo a string estática por acentos invertidos. Em vez de meninos, aqui, podemos interpolar nosso SearchString. Agora, vamos testar o corpo do log do console. Mais uma vez, eu refresco. Eu digito garotas. Eu clico em “Pesquisar”. Se eu olhar dentro da guia de rede, posso ver que envio programas de pesquisa para garotas de consulta. Se eu digitar outra coisa, você pode ver que será outra coisa. Se eu digitar alguma bobagem, será sem sentido. Nosso pedido é dinâmico. Quão legal é isso? Agora você sabe como poderemos buscar dados. Você pode ver que tudo está conectado agora em uma única peça dessas poucas linhas. Ótimo. Usamos a API TVMaze. Você pode lê-lo completamente. É muito simples com bons exemplos, basta folhear rapidamente a caixa. No próximo vídeo, vamos tornar essa função reutilizável e tentaremos exibir os resultados que recebemos aqui da API. Vamos tentar exibi-lo dentro de nossa marcação JSX. Deixe-me confirmar as mudanças que fizemos. Vou clicar no sinal de adição. Vou parar o aplicativo e dizer: deixe-me ver quais mudanças eu fiz? Digamos que pesquise filmes ou pesquise programas com o clique do botão. Digamos que tenha adicionado uma caixa de texto ou uma pesquisa. Pesquise programas ao clicar no botão. Algo parecido. Em seguida, faça o upload para o GitHub e até o próximo. Nos vemos lá. 64. 08 renderização mostram dados da API do TV Maze: Olá de novo. Neste vídeo, finalmente exibiremos os resultados que obtemos da API. No último vídeo, descobrimos como podemos consultar dados com base no que digitamos dentro do elemento de entrada. Desta vez, vamos tentar exibir os dados que recebemos da API TVMaze que usamos para consultar dados. Vamos embora. Se voltarmos ao nosso código, teremos a seguinte lógica para buscar dados. No entanto, também usaremos a mesma lógica em outras páginas. Por que não criamos um invólucro muito simples em torno dessas funções para que seja mais fácil reutilizá-las em outros arquivos? O que vou fazer dentro do código-fonte é criar uma nova pasta, que vou chamar de algo como API ou talvez como utils ou você pode chamá-la do que quiser. Basta separá-lo do resto da lógica do resto do arquivo e será mais fácil encontrá-lo. Aqui, eu vou criar um arquivo chamado tvmaze.js, e dentro desse arquivo, o que eu vou fazer? Vou criar uma função reutilizável que chamaremos de ApiGet. Esse ApiGet receberá apenas o nome do caminho da URL , exatamente como você vê na documentação. Só passaremos esse segmento de URL para a função, e a função fará o resto. Em vez de fazer isso, chamaremos apenas ApiGet e, em seguida, passaremos programas de pesquisa e cadeias de caracteres de consulta, algo assim. No entanto, podemos ir ainda mais longe e criar outro invólucro para isso. Em vez de usar essa função dessa forma, podemos simplesmente chamar a função search for shows e, em seguida, passar a string de pesquisa, e pronto, e o resto, toda essa lógica aqui, será gerenciada internamente. Muito legal. Vamos seguir em frente e implementar isso. Antes de tudo, precisamos criar esse ApiGet para que possamos usá-lo dessa forma. Esse ApiGet será uma função que retornará como uma promessa, que será o corpo da resposta, assim como aqui. Eventualmente, vai ficar assim. Vamos seguir em frente e fazer isso. Passamos a queryString aqui. O primeiro argumento que essa função receberá será queryString. Essa função usará buscar essas duas linhas. Vou copiá-los daqui. Como usamos a palavra-chave await aqui, pretendemos usar async-await, então eu marco essa função como async e, a partir dessa função, retorna o corpo. No entanto, obtemos esse URL codificado aqui. Podemos movê-lo para fora apenas para, de alguma forma , declará-lo em algum lugar no topo para que saibamos o que é o BASE_URL aqui. Aqui no topo, vou apenas criar uma variável chamada BASE_URL e será https://api.tvmaze.com sem barra inicial. Então, vou interpretá-lo na chamada de busca BASE_URL. Em vez de usar barras de pesquisa mostram e depois uma string de pesquisa, vou aplicar aquela queryString que passamos como argumento, que será essa string com a barra inicial. Em vez de tudo isso, vou usar apenas queryString. Eventualmente, nosso URL ficará assim. Ele pegará BASE_URL e pegará a queryString que passamos dos argumentos. Eventualmente, esse tipo de URL será formado. Agora, vamos em frente. Concordamos em ir mais longe do que o ApiGet e criamos outra função em cima do ApiGet que chamamos de SearchForShows, para não passar barras de pesquisa com barras. Se você quiser gerenciar isso, ele será gerenciado em um único local, em um único arquivo aqui dentro de tvmaze.js. A partir daqui, vou exportar porque vamos usá-lo mais tarde na função inicial chamada export const searchForShows. Novamente, essa função receberá apenas o queryString, exatamente o que digitarmos dentro da entrada. Será uma consulta. Vamos chamá-la apenas de consulta. Essa função que chamaremos de ApiGet e passará pesquisas, shows e consultas será a consulta que passamos. Chamaremos isso de ApiGet e tudo o que o ApiGet retornar será retornado do SearchForShows. Estou usando aqui a sintaxe curta das funções de seta. Essa sintaxe, sem usar explicitamente o corpo da função com colchetes , retorna tudo o que o ApiGet retorna. Isso é o mesmo que escrever return ApiGet. Para encurtá-lo, nós o usamos assim. Eu o salvo e agora posso usar esse SearchForShows dentro da minha casa.jsx. Vou importar de, vamos voltar para o nível acima. Pegamos um labirinto de api/tv e pegamos o SearchForShows. Agora, podemos remover tudo isso e chamar SearchForShows com o queryString, que será nosso SearchString. Assim. Se virmos os resultados, vamos chamá-lo de ApiData e registrar ApiData, e voltaremos ao aplicativo. O que quer que digitemos aqui, vamos inspecionar a guia Rede. Nós digitamos garotas, pressionamos “Enter”. Você pode ver que a solicitação está sendo formada corretamente, o URL da solicitação está correto. Tudo funcionou perfeitamente. Se olharmos dentro do console, podemos ver que na linha 15 do home.jsx, exatamente onde temos nosso log do console, é isso que recebemos. Este é o nosso API Data. Agora, o que podemos fazer? Podemos criar outro estado e, quaisquer dados que recebemos aqui, podemos colocá-los dentro do estado porque, novamente, esses dados de API que recebemos são dados que mudam ao longo do ciclo de vida do componente porque são dados que pesquisamos. Ela pode estar vazia, não pode ser carregada, algo pode estar carregada com ela. Vou seguir em frente e aqui vou criar um novo estado, que chamaremos de showsResult ou vamos chamá-lo apenas de ApiData e setApiData, e ele será usado no estado aqui. Por padrão, será uma matriz vazia ou talvez seja nula por padrão. Aqui, o que vou fazer, essa variável de comprimento 15, vou chamá-la de resultado ou resposta. Sim, vamos chamá-lo de result e eu vou chamar setApiData, e setApiData será o resultado. Qualquer que seja a matriz que recebermos aqui, nós a colocaremos dentro do nosso estado ApiData. Então, já sabemos o que fazer com as matrizes. Você se lembra disso. Podemos mapear cada elemento para algum JSX Barker e depois exibir. O que faremos logo abaixo do formulário. Vamos criar um div aqui. O que faremos, criaremos uma função aqui. Em vez de embutir o método de mapa de pontos ou vamos primeiro embutir esses métodos de mapa de pontos. Há uma coisa a ter em mente ao mapear. Vamos chamar o mapa ApiData. Temos dados aqui e, por enquanto, vamos mapeá-los para uma div simples. Vamos inspecionar que tipo de dados temos aqui. Qual é a forma dos dados? Temos uma variedade de objetos. Se inspecionarmos esse objeto de dados que representa esse objeto que eu destaquei, ele tem a chave de pontuação e , em seguida, a chave show. Dentro do show, temos o nome, temos o URL do ID. Por enquanto, vamos exibir apenas o nome. Precisamos acessar data.show. Se eu interpolar data.show.name. Você sempre deve se lembrar que precisa passar o suporte da chave. chave precisa ser algo único, pois lidamos com dados da API, os dados da API quando vêm de acenados geralmente têm ID e o ID representa o item de forma exclusiva. ID é o estojo perfeito para o suporte de chave. Os dados mostram o ID para identificar de forma exclusiva o elemento mapeado. Vamos tentar. Nós acessamos o aplicativo e o que temos aqui? Já temos o erro que diz: não é possível ler as propriedades de nulo, lendo o mapa. Se eu atualizar a página, sempre verei esse erro. O que acontece? O fato é que nosso estado inicial aqui é nulo. Isso significa que, quando o componente for renderizado, os dados da API de estado serão nulos. Como não clicamos em nenhum botão, não obtivemos nenhum resultado. O estado é nulo. Se tentarmos mapear null, obteremos esse erro porque, basicamente, nosso código tem a seguinte aparência, null.map. Bem, isso está errado. É por isso que vemos esse erro. Diz que não é possível ler propriedades de nulo, lendo o mapa. O que significa que ele tenta fazer null.map. Como podemos superar isso? Podemos fazer isso de várias maneiras. A maneira mais fácil de lidar com isso é mudar o estado inicial de nulo para um array vazio. Deixe-me voltar aos dados da API. Se a mudarmos para uma matriz vazia, sempre que não tivermos nenhum dado, já que a matriz está vazia, não veremos nada. Porque bem, nada será mapeado em última análise. Quando pesquisamos algo como para meninos e quando obtemos nossos resultados da API, cada elemento da API é mapeado para a div correspondente com o nome do show. No entanto, o que eu quero mostrar alternativamente é que, em vez de usar uma matriz vazia como estado padrão, ainda podemos usar null, mas podemos lidar com nossa lógica de forma um pouco diferente. Vamos além e vamos criar uma função auxiliar que chamaremos de renderApiData. Em vez de inserir o método.map aqui diretamente, que chamará como você lembra, já fizemos isso, renderApiData e gerenciaremos uma lógica de renderização condicionalmente dentro dessa função. Aqui eu vou criar RenderApiData. Em vez de usar isso, direi que nosso estado inicial é nulo, lembre-se. Quando tentamos exibir nulo, obteremos um erro porque, bem, não podemos mapear nulos. Podemos simplesmente verificar se os dados da API são nulos ou se nossos dados de API são falsos, retornamos nulos. Caso contrário, sabemos que definitivamente será uma matriz depois de configurada. Ou talvez possamos inverter a lógica para que ela seja mais legível e melhor. Nós podemos dizer. Se tivermos dados de API, se os dados forem verdadeiros , não serão nulos. É algo, por exemplo, como uma matriz. Nesse caso, chamamos o método.map para retornar ApiData, map, data e, em seguida, a lógica que temos. Caso contrário, por padrão, se essa condição falhar e nossos dados de API forem falsos , eles passarão por aqui, passarão por essa condição. Então, por padrão, não retornamos nada. Lembre-se de que resultados nulos em nada serão renderizados dentro da marcação JSX. Se voltarmos ao aplicativo, você verá que nada é exibido. Isso porque nossos dados de API foram inicialmente definidos como nulos. É por isso que renderizamos como nulo. Mas assim que eu procuro a API, tenho meus dados aqui. Incrível. Sempre que eu mudar a consulta, ela será atualizada. Olha só isso, como é? Mais uma coisa que eu quero acrescentar aqui é, na verdade, o tratamento de dados. Eu sei que já cobrimos muita coisa e é muita coisa. Mas e quanto aos erros? Se nossa solicitação que enviamos aqui, se olharmos dentro da rede, se a solicitação que enviamos aqui falhasse por algum motivo, geraria um erro. O que acontece nesse caso? Na verdade, podemos emular esse erro na busca por shows ou nos dados da API. Então, em vez de apenas fazer uma pesquisa na API, podemos simplesmente gerar um erro até que algo ruim aconteça. Isso é exatamente o que acontecerá se essa solicitação falhar por algum motivo, algo ruim aconteceu. Vamos tentar ver. Temos um código inacessível, que novamente vem do eslint. Eslint, você me salvou muito. Por enquanto, vamos apenas comentar isso. Vou procurar qualquer coisa, algo como olá. Se eu clicar, nada acontece. Mas você pode ver aqui dentro do console que não detectamos um erro de promessa, algo ruim aconteceu. Nesse caso, precisamos sempre lembrar quando lidamos com JavaScript assíncrono, quando lidamos com APIs, sempre precisamos detectar e lidar com erros, não importa o que aconteça, mesmo que você tenha certeza sobre essa API, de quão boa ela é e possa pensar em qualquer erro. Bem, você precisa mudar sua mentalidade. Algo acabará por trazer um erro, então você precisa ter certeza de como lidar com isso. Nesse caso, dentro dessa busca de espera por programas, podemos encapsulá-la e tentar capturar o bloco para detectar quaisquer erros. Vou mover essas duas linhas para dentro da tentativa. Se algo dentro do bloco try falhar, ele emitirá o erro dentro do bloco de captura. Podemos criar outro estado, e qualquer erro que recebamos aqui, podemos colocá-lo dentro do estado. Aqui na parte superior, vou criar ApiDataError e o estado setApiDataError. Por padrão, também será nulo. Vou seguir em frente e, dentro do bloco catch, vou chamar setApiDataError para qualquer erro que tenhamos aqui. Agora, se tentarmos cancelar o erro de log, o estado, por padrão, é nulo. Mas sempre que temos um erro, podemos ver que temos o outro objeto dentro do nosso estado. Podemos usá-lo dentro do RenderApiData e exibir qualquer mensagem de erro caso haja um erro. Podemos dizer se temos ApiDataError. Nesse caso, exiba div, que diz que ocorreu um erro, e podemos interpolar ApiDataError.message, pois nosso ApiDataError será o objeto de erro. Vamos tentar. Se você se lembra dentro do API Gateway, algo ruim aconteceu. Dizemos que não importa. Clicamos em Pesquisar e agora vemos que ocorreu um erro, algo ruim aconteceu. Legal. No entanto, também precisamos lembrar que precisamos atualizar esse estado caso cliquemos uma vez em Pesquisar vermos que esse erro ocorreu. Em seguida, clicamos na próxima vez em Pesquisar e, em seguida, a próxima solicitação será processada. No entanto, nossos dados de API em nosso estado estão pendentes. Ele ainda tem seu estado anterior, então será exibido. Precisamos ter certeza de que o limpamos antes de cada solicitação que enviamos. Chamamos setApiDataError para saber o estado inicial. Assim, gerenciamos todo o fluxo de nossa solicitação. Agora podemos remover o novo erro e unificar a lógica. Vamos ver tudo mais uma vez em ação. Procuro meninas, tenho meninas, tenho meninos e tenho tudo o que digito aqui. Tudo funciona conforme o esperado. Caso tenhamos um erro gerado pela API, ele será tratado aqui. Como podemos testar isso? Na verdade, podemos simplesmente digitar algumas bobagens no euro e ver o que a API nos fornece. Eu datilografei garotas. Eu clico em Pesquisar. Você pode ver dentro da guia Rede, agora ela está vermelha. Diz 404, o que significa que fizemos algo errado. Obviamente, esse endpoint não existe. Nossa API para a API VMAs retornou algum erro. No nosso caso, ele retornou um erro. Ele acabou de retornar uma mensagem de status 404. Fetch entendeu que era um erro, mas não tinha nenhuma mensagem de erro. Diz que falhou na busca por padrão. Agora, se tentarmos alterá-lo novamente. Se procurarmos garotos. Agora, tudo foi exibido. Quão legal é isso? Eu acho que parece incrível. Lidamos com todas as situações possíveis que poderiam dar errado. Agora temos uma lógica bastante robusta, não apenas para criar dados, mas também para lidar com quaisquer erros, além de exibir os dados que vêm da API, algo assim. Acho que, na verdade, abordamos muita coisa aqui. Falamos sobre estados diferentes, falamos sobre busca de dados, falamos sobre captura de erros, falamos sobre exibição de dados. Isso é muito. Vamos encerrar tudo. Git add, git commit. Vamos chamá-lo de buscar e exibir dados da API tvmaze. Crie uma função reutilizável para buscar dados. Para função reutilizável, refiro-me à busca por programas. Incrível. Vamos nos comprometer e nos esforçar para dominar tudo. Eu vou te ver na próxima. 65. 09 Fix Prettier não funciona: Olá. Este vídeo vai ser rápido porque acabei de notar um pequeno problema na configuração do projeto. O problema é esse arquivo prettierc. Então, digitei incorretamente o nome do arquivo e, por causa disso, o conflito que especificamos aqui não funcionou. No entanto, você deve ter notado que, quando eu estava salvando arquivos, eles estavam fora de formação. Isso ocorre porque temos a extensão Prettier instalada e, por padrão, quando essa extensão não consegue encontrar a configuração colocada em seu projeto, ela retornará à configuração definida em algum lugar internamente dentro dessa extensão. É por isso que ainda funcionou. No entanto, não usou esse conflito. Para corrigir isso, deixe-me renomear esse arquivo para prettierrc. Então, agora ele pode realmente ser captado. Se eu acessar, digamos, o componente do aplicativo e salvá-lo, agora você vê que eu realmente tenho aspas simples, conforme definido em um conflito mais bonito. No entanto, para corrigir o pequeno problema, preciso examinar cada arquivo dentro da fonte. Pode ser entediante e não temos muitos arquivos, então podemos fazer isso manualmente, mas aqui vai uma dica. Podemos usar uma interface de linha comum mais bonita e escrever um pequeno script que formará fonte interna de um arquivo antigo. Se eu acessar a Documentação do Prettier, clico em Documentos e , na seção Uso, posso procurar CLI, posso encontrar esse trecho aqui. Na prática, isso pode ser mais ou menos assim. Eu posso simplesmente copiar este. Vá para o pacote JSON, defina um novo script aqui, que chamarei de formato, onde escreverei um traço mais bonito, dash, write dot. O Dot formatará todos os arquivos no diretório atual, mas eu não quero fazer isso. É por isso que vou alterá-lo para fonte dot blast streaks, asterix, dot e, em seguida, colchetes curvos, JS, JSX. Não entre em pânico, isso é algo chamado padrão global ou sintaxe global. Ele é usado para combinar arquivos e o Prettier pode aceitar esse padrão ou sintaxe como argumento. Portanto, ele procurará todos os arquivos dentro do código-fonte e em subpastas antigas e procurará apenas arquivos com extensão dot JS e dot JS6. Eu vou salvá-lo. Vou fazer o formato de execução do NPM. Vamos ver o que temos. Agora, podemos ver a saída. Então, esses são todos os arquivos que foram formatados pelo script de formatação por recurso. Este é mais bonito aqui a que me refiro, ele será retirado dos módulos do Node porque o instalamos como uma dependência de desenvolvimento. Então, escrevemos mais bonito aqui dentro dos scripts do NPM e ele será resolvido como o mais bonito instalado a partir dos módulos do Node, tão simples quanto isso. Agora que tudo foi corrigido, vamos confirmar tudo e dizer que corrigiu o erro ortográfico de configuração mais bonita, adicionar script de formato ao pacote JSON. Incrível. Nos vemos na próxima. 66. 10 botões de rádio: Olá. Neste vídeo, continuaremos com o desenvolvimento da página inicial e, desta vez, adicionaremos botões de rádio em nosso formulário que usamos para pesquisar os resultados, e poderemos selecionar se queremos procurar programas ou procurar atores. Vamos embora. Vou voltar ao componente inicial, dentro do componente inicial, logo abaixo da entrada do texto do tipo, vou criar outra entrada aqui, já que será um botão de rádio, vou colocá-la dentro do elemento do rótulo, então será uma entrada do tipo. etiqueta da rádio será shows, o nome será SearchOption, o valor desse botão de rádio será shows. Então eu vou criar outra entrada, outro botão de rádio, desta vez para atores. Atores, tipo rádio, nome permanece o mesmo porque esses dois botões de rádio compartilham o mesmo estado, valor serão os atores. Volto à minha marcação e vejo que as caixas de seleção estão lá, desculpe-me, botões de rádio. Agora, para que possamos incluir de alguma forma o valor, a seleção de nossas caixas de seleção na solicitação da API, precisamos ter outro estado para esses botões de rádio. No topo, vou criar outro estado, que chamarei de SearchOption, algo assim, algo assim, defina SearchOption por padrão, ele será exibido. Nosso estado SearchOption pode ser shows ou atores, mostra string ou string de ator. Com base nisso, enviaremos a solicitação relevante para a API TVMaze. Agora, precisamos associar esse estado que acabamos de criar aos botões de rádio que escrevemos anteriormente. É praticamente o mesmo que com a entrada do tipo texto, vamos fazer uma vinculação bidirecional de dados , já temos valor, agora precisamos ouvir o evento de mudança nessas entradas. A lógica é exatamente a mesma Vou apresentar aqui o manipulador de eventos on change, que chamarei de mudança de rádio, e será o mesmo para os dois elementos aqui no canto superior direito ao lado dele. OnSearchInputChange, escreverei sobre mudança de rádio, ele também recebe o objeto de evento e agora, para definir o estado de searchOption, posso me referir ao atributo de valor que passamos para cada botão de rádio correspondente. Os botões de rádio são representados por valores para que possamos realmente acessar event.target, que será resolvido no elemento HTML de entrada. Eles têm um atributo de valor e isso nos dará o valor correspondente que associamos a cada um dos rádios. SetSearchOption será event.target.value, basicamente o mesmo que fizemos com onSearchInputChange. Agora, essa é uma vinculação de dados unidirecional, como você se lembra, mas ouça as alterações dentro do rádio, mas não associamos o estado searchInput ao elemento de entrada, então já temos o atributo de valor aqui, mas o estado do botão de rádio é representado não pelo atributo value, mas pelo atributo check, e nosso botão de rádio mostra marcado quando nossa SearchOption é igual a shows, para que possamos escrever desse jeito. Pesquise programas iguais a shows. Essa expressão será verdadeira quando a busca por shows for uma sequência de caracteres. Exatamente a mesma lógica que vamos aplicar para a contribuição dos atores. Isso será verificado somente quando a busca por programas for igual a atores. Ótimo. Agora vamos dar uma olhada. Vamos registrar o SearchOption no console e, desculpe-me, ainda diz que usei a pesquisa de programas aqui, desculpe, eu pretendia usar o SearchOption, se o estado for igual a shows, essa entrada será verificada. O mesmo vale para atores. Ótimo. Agora vamos tentar registrar o SearchOption no console apenas para ter certeza de que fizemos tudo certo. Por padrão, é mostrado que esse é o estado inicial. Se eu selecionar atores, agora, são atores, se eu selecionar programas novamente, ainda são shows, o que significa que tudo funciona perfeitamente bem. Agora, precisamos de alguma forma inserir esse estado de SearchOption em nossa solicitação e colocar a lógica correspondente em algum lugar dentro do manipulador de pesquisa on. No momento, vamos simplificar, mas no próximo vídeo, vamos refatorar um pouco esse componente e fazer com que pareça muito, muito melhor. Mas qual será a lógica em primeiro lugar? Se voltarmos à documentação da API TVMaze, usamos esse ponto final aqui para procurar os programas. Se olharmos dentro do índice, há outro link que nos leva à seção de pesquisa de pessoas aqui, e é quase o mesmo que nos programas. Você pode ver que, bem, o modelo é basicamente o mesmo, mas desta vez procuramos pessoas em vez de programas, para saber como podemos conseguir isso em nosso código. Se voltarmos ao TVmaze.js, aqui já temos essa função reutilizável chamada search for shows. Podemos copiar essa função e renomeá-la para SearchForPeople e, em vez de passar /search/shows para a API get, passaremos /search/people, e todos os argumentos permanecerão os mesmos porque também temos uma string de consulta aqui. Incrível. Voltamos ao homejsx, desta vez importamos o SearchForPeople. A lógica interna do manipulador de pesquisa será muito simples. Se SearchOption for igual a shows, execute essa lógica que já temos, caso contrário, execute a mesma lógica, mas chame searchForPeople. Você pode ver que temos uma pequena repetição aqui, mas vamos ajustar isso no próximo vídeo. Por enquanto, não pense muito sobre isso. Vamos ver como fica. Voltamos ao nosso aplicativo, mostramos os programas selecionados por padrão, procuramos algo e você pode ver que tudo funciona conforme o esperado. Se selecionarmos atores e clicarmos em “Pesquisar”, teremos uma tela em branco, o que aconteceu? Se olharmos dentro da guia de rede, ainda podemos ver que a solicitação foi processada com o endpoint correto /search/people, mas se olharmos dentro do console, temos esse cabeçalho, que diz que não é possível ler as propriedades do nome de leitura indefinido. O que aconteceu? Se observarmos o corpo da resposta que recebemos da API, esse é o objeto que temos, mas dentro do código, mas dentro do código na verdade escrevemos que, se tivermos o estado dos dados da API, renderizaremos data.show.id ou data.show.name, mas no resultado de nossos atores, não temos isso. Não temos data.show, temos data.person. Basicamente, estamos acessando os dados errados. console aqui nos fala sobre isso. Não é possível ler propriedades do nome de leitura indefinido, porque data.show é indefinido dentro desse objeto de resposta e, em seguida, tentamos acessar undefined.name, e é isso que vemos, não podemos ler propriedades do nome de leitura indefinido. Esse é o nosso problema. A solução para isso será que em algum lugar aqui, precisaremos escrever, quando procurarmos atores ou quando tivermos, digamos, resultados de atores, exiba atores, mas quando tivermos resultados de programas , exiba programas, e não podemos fazer a mesma lógica que aqui. Não podemos confiar em nosso estado, precisamos confiar na forma de dados que temos. Aqui dentro da lógica, podemos simplesmente fazer se, onde está? Temos uma matriz, vamos perguntar: se o primeiro elemento dos dados da API tem a propriedade show, nesse caso, podemos dizer que estamos trabalhando com os shows, temos os dados mostrados da API. Caso contrário, se não tivermos shows, se nosso primeiro elemento dentro dessa matriz não tiver a propriedade show, podemos dizer que estamos trabalhando com as pessoas aqui, com esse objeto de pessoa. Vamos dizer o contrário, execute ApiData.map e os dados desta vez não serão mostrados, mas data.person. pessoa de dados, vamos ver, também se identifica e a pessoa dos dados, digamos, o nome, praticamente da mesma forma que com os programas. Agora vamos tentar. Parece um pouco confuso, não se preocupe, vamos consertar tudo isso um pouco mais tarde. Vamos ver se tudo funciona. Eu procuro programas, obtenho resultados da API, eles são renderizados, perfeitos. Eu mudo para atores e procuro algo como Andrew e agora você pode ver que não temos nenhum somador, console está limpo, obtemos a resposta na guia da rede e temos os dados renderizados, então podemos ver que funcionou. Incrível, não é? Ótimo. dizer que alcançamos o que queríamos por enquanto, vamos confirmar nossas mudanças e, no próximo vídeo, vamos refatorar levemente esse componente e encapsular lógica que temos com o elemento do formulário aqui em um componente separado. Mas, por enquanto, vamos cometer tudo, e nomear esse commit como, deixe-me ver, adicionar busca por atores. Ótimo. Vamos para o GitHub e nos vemos na próxima. 67. 11 Movendo a lógica do formulário de busca para seu próprio componente: Olá de novo. Neste vídeo, continuaremos trabalhando com nossa lógica que apresentamos no vídeo anterior. Adicionamos uma opção para selecionar programas ou atores e, com base nessa seleção, enviamos a solicitação correspondente para a API TV maze. Você pode ver que, uma vez que adicionamos essa lógica, nosso componente doméstico ficou um pouco inchado com muitas lógicas diferentes. Na verdade, podemos simplificá-lo e é exatamente isso que vamos fazer agora. Por que não movemos toda essa lógica relacionada ao elemento do formulário, todos esses estados, por que não a movemos para um componente separado e colocamos a lógica lá, e então vamos expor apenas o que precisamos por meio de sondas. Vamos tentar fazer isso. Dentro da pasta de componentes, vou criar um novo componente, algo como searchformjsx. A partir daqui, vou exportar o componente do formulário de pesquisa. Mas agora será apenas um div vazio com formulário de pesquisa padrão para exportação. Então, agora vamos tentar uma coisa importante e vamos ver o quão aproximadamente queremos que esse componente se comporte para que possamos escrever a lógica de forma correspondente. Vou importar o pesquisa do formulário de pesquisa de componentes. Em vez de tudo isso, o que vai escrever um formulário de pesquisa. O que precisamos? Queremos realizar a pesquisa em algum lugar aqui nesse componente porque esse é o componente em que realmente renderizamos os dados. Se quiséssemos gerenciar tudo dentro do formulário de pesquisa , não poderíamos acessar essa lógica de fora. Vamos gerenciar a lógica de estado com entradas dentro do componente , mas a pesquisa realmente acontecerá aqui. A lógica de pesquisa será escrita dentro do JSX doméstico. Precisamos, de alguma forma, encontrar uma maneira expor uma sonda que nos permita pesquisar programas aqui dentro do JSX doméstico. Na verdade, podemos simplesmente passar essa função de pesquisa para o formulário de pesquisa e o formulário de pesquisa de insights quando clicamos em enviar, que chamará a função definida aqui na página inicial. Vamos chamá-la de algo como na pesquisa e passaremos nossa função de concerto que já temos , mas modificaremos um pouco a lógica. Em vez de escrever tudo isso, teremos apenas uma única linha. Agora, vamos copiar essa marcação com o elemento de formulário que temos e colocá-la dentro de um formulário de pesquisa como este. Agora, precisamos mover a lógica que temos no JSX doméstico para seu estado, como na alteração da entrada de pesquisa e na mudança de rádio. Vamos mover tudo isso para o formulário de pesquisa. Aqui, também esses estados, opção de pesquisa e sequência de pesquisa. Vamos copiar esses dois. Vamos colocá-los aqui em cima. Precisamos importar o estado de uso agora. Vou copiar isso também. Agora, a única coisa que perdemos aqui é o gerenciador de pesquisa. Vamos seguir em frente e defini-lo aqui. Em vez de ligar para isso na pesquisa, ligaremos para o envio, o motivo será o seguinte. Podemos passar isso para o manipulador de pesquisa aqui diretamente como uma sonda e depois especificar diretamente como no manipulador de envio mas exporemos o objeto do evento, que significa que teremos que escrever a lógica para evitar o evento de envio. No entanto, o componente externo que é o Home.jsx realmente não precisa saber disso. Por que eu realmente preciso evitar alguma lógica padrão, algum comportamento padrão? Podemos mover parte dessa lógica da pesquisa diretamente dentro do componente do formulário de pesquisa. Aqui, vou criar a função ao enviar e passá-la como atributo no envio. Novamente, temos o objeto de evento dentro dessa função. Impedimos a ação de envio padrão chamando event prevent default e, logo em seguida, precisamos executar essa lógica. Mas essa lógica será definida aqui. Podemos esperar o suporte de pesquisa , que será uma função, e simplesmente o chamaremos aqui, sem mais nem menos. Vamos tentar. Aqui, em vez de escrever event prevent default, não precisamos dele porque isso já foi feito dentro do componente do formulário de pesquisa, vou removê-lo. No momento, chamamos de busca própria sem nenhum argumento, o que significa que não recebo nada aqui. Apenas uma função sem argumentos. No entanto, perdemos a opção de acesso à pesquisa e perdemos o acesso à string de pesquisa. Para corrigir isso, sempre que chamamos a função de pesquisa que definimos dentro de casa, podemos passar argumentos aqui porque o temos aqui dentro do formulário de pesquisa. Por que não chamamos a sequência de pesquisa na web e a opção de pesquisa? Mas, para torná-lo mais fácil de usar, a API que expomos do componente do formulário de pesquisa para torná-la fácil de usar aqui, podemos passar que pode ser um objeto, algo como opções. Consulta, que seja apenas Q será a string de pesquisa e a opção de pesquisa, vamos mantê-la como está. Eventualmente, teremos um objeto chamado options com propriedade Q e propriedade de opção de pesquisa. Vamos passar esse objeto para a função on search. Aqui recebemos o objeto de opções e podemos fazer a desestruturação diretamente aqui. Vamos desestruturar a propriedade Q e a propriedade da opção de pesquisa. Pegamos Q, pegamos a opção de pesquisa em vez da string de pesquisa. Agora vamos usar Q. Vamos tentar ver. Se eu atualizar a página, nada acontece porque eu não executei o servidor de desenvolvimento. Deixe-me fazer isso muito rapidamente. Vamos esperar um segundo. Está aqui. Deixe-me refrescar. Vamos ver. Nossa funcionalidade não deve realmente ser alterada porque estamos apenas fazendo um fator menor aqui. Esperamos que tudo se comporte exatamente da mesma forma que antes. Meninas, temos garotas, funciona perfeitamente, atores. Digamos que, Garry, temos Garry. Você pode ver que a funcionalidade permanece a mesma, mas agora nossa lógica dentro de um JSX doméstico foi drasticamente simplificada. Basicamente, não temos quase nada aqui, exceto a lógica relacionada à pesquisa em si. A lógica que cuida da forma de todas as entradas foi encapsulada dentro do formulário de pesquisa. Agora, separamos as preocupações. Faz sentido. Eu acho que sim. É isso por enquanto. Na verdade, espere, não é isso. Ainda precisamos fazer algo a respeito, porque você pode ver que ainda temos uma pequena repetição aqui. Na verdade, podemos continuar assim e não pensar muito sobre isso. Não há nada de errado com isso, mas podemos simplificar. Digamos que primeiro crie uma variável chamada resultado. Assim, moveremos os dados da API do conjunto para cá e faremos algo assim. Ou talvez possamos até simplificar alinhando a lógica com operadores ternários, mostrados na opção de pesquisa. Aguarde a busca por programas, caso contrário, aguarde a busca por programas, caso contrário, aguarde as pessoas. Mas acho que essa declaração serve. Incrível. Agora é totalmente isso. Vamos comprometer tudo o que acabamos de fazer. Como podemos nomear isso? Podemos nomear isso de forma muito simples. Nós apenas o chamamos de lógica do formulário de pesquisa fatorado ou, digamos , oscilado, e componente do formulário de pesquisa. Perfeito. Te vejo na próxima. 68. 12 Mostrando cartas para shows e atores: Oi. Neste vídeo, continuaremos com o desenvolvimento e continuaremos com a exibição dos dados da API TV maze. Neste momento, nossa lógica para exibir dados é muito básica. Simplesmente mapeamos o estado dos dados da API e, em seguida, exibimos o acrônimo ou o nome do programa. Vamos tornar isso real desta vez. Então, em vez de escrever isso, podemos, novamente, oscilar toda essa lógica em um componente separado, especificamente para atores, e em outros componentes, especificamente para shows. Vamos fazer isso. Dentro da pasta de componentes, vou criar mais duas pastas aqui, uma para atores e outra para shows. Nessas pastas, colocaremos componentes específicos relacionados apenas a programas ou relacionados a atores. Dentro da pasta shows, vou criar um novo componente, que chamarei de ShowGridJSX. Agora, será o ShowGrid padrão de exportação div e, para referência futura, vou copiar essa lógica e colocá-la dentro do ActorsGrid também. Mas vou renomeá-lo para ActorsGrid desta vez. Agora vamos voltar para casa. Agora, em vez de fazer isso, em vez de mapear elementos aqui diretamente, podemos exibir ShowGrid ou ActorGrid. Quando tivermos shows, exibiremos o ShowGrid. Você pode ver o intellisense novamente. No menu suspenso, pressiono “Tab” e verifiquei se ele foi importado corretamente. Bem, foi, então eu posso continuar. O mesmo que farei com os atores, em vez de mapear elementos aqui, vou exibir o ActorsGrid. O intellisense, boom, importado. Eu verifiquei a entrada. Parece ótimo. Muito mais simples agora, não é? Para que possamos exibir dados dentro desses componentes, precisamos passar dados para que eles possam , de alguma forma, manipulá-los internamente. Para o ShowGrid, vamos passar shows prop, e serão dados da API. Para a grade de atores , serão os atores, novamente, dados da API. Por enquanto, terminamos com o componente doméstico. Toda a lógica será colocada no componente de grade correspondente. Vamos começar com os shows primeiro. Vamos ao ShowGrid, aqui, recebemos o adereço do programa que passamos aqui do homejsx. Ótimo. Agora, dentro do Mostrar grade, vamos mapear os dados agora. Vamos escrever showsgrid.map. Aqui temos nosso objeto de dados. Por enquanto, vamos nos lembrar rapidamente: o que temos? Temos data show.name, se eu não estiver errado, e para a chave, vou passar dados, mostrar ID. Vamos verificar isso rapidamente. Vamos voltar ao aplicativo. Eu digito algo e recebo um erro, que diz que não é possível tratar propriedades de indefinido. Acho que entendo agora. O problema é que lidamos com o caso quando temos estágio igual a nulo. Mas nós realmente não resolvemos o caso quando o palco é uma matriz vazia. Porque você viu que eu digitei algo sem sentido agora, mas se eu digitar algo sensato e realmente tivermos resultados da API, teremos uma matriz. Mas se eu digitar algo sem sentido, será uma matriz vazia. Se olharmos dentro da guia de rede, você pode ver na API em sua pré-visualização que temos uma matriz vazia e não lidamos com isso aqui. Mas na lógica que escrevemos, verifique o primeiro elemento dentro da matriz. Mas como o primeiro elemento não existe, ele é indefinido, temos undefined.show, basicamente. Precisamos consertar isso. Precisamos considerar o caso quando temos uma matriz vazia. Aqui, vamos adicionar outra condição if, se apidata.length for igual a zero. Você pode ver o que eu fiz aqui. Na verdade, adicionei esse ponto de interrogação aqui. Isso é chamado de encadeamento opcional porque, se os dados da API forem nulos e eu digitar null.length, receberei um erro. Para evitar esse erro e garantir a duração do acesso ao JavaScript somente quando os dados da API forem verdadeiros, podemos adicionar esse ponto de interrogação aqui. Se os dados da API forem falsos, são nulos, não gerará um erro dizendo que é possível ler o comprimento da propriedade de nulo. Mas quando for verdade, ele prosseguirá e usará a propriedade length. Se apidata.length for igual a zero, se nossa matriz estiver vazia, não exibiremos nenhum resultado. Vamos tentar ver se eu digitar sem sentido, obtemos uma matriz vazia da API e, desta vez, não temos textos de resultados. Parece bom para mim. Vamos digitar algo que faça sentido. Temos garotas, a lógica que mostra todos os programas mais antigos está escrita dentro do ShowGrid. Parece perfeitamente bom. Agora, vamos criar o componente de cartão para o show. O componente do cartão será nosso estilo show-card, onde vemos todos os dados sobre o programa em vez de apenas mostrá-los em uma div simples. Dentro da pasta shows, vou criar ShowCardJSX. Isso vai ser um show card. Novamente, div simples e, por padrão, exportamos o ShowCard. Agora vamos usar esse show-card aqui dentro do ShowGrid. Em vez de mapear cada elemento, cada objeto show para aquela div simples, vamos mapear cada elemento para o componente show card. Em vez de fazer isso, vou mapear cada elemento para o ShowCard. Novamente, insira Alto, e eu precisarei passar adereços para o componente ShowCard. No entanto, está tudo vermelho porque, novamente, preciso passar o suporte da chave. Não importa se o elemento é seu próprio componente personalizado ou se é apenas um elemento HTML, você sempre precisa passar a chave. A chave será a ID do show de dados. Agora, quais dados queremos exibir dentro do ShowCard? Vamos começar com algo simples. Então, primeiro vamos receber o nome prop, e provavelmente vamos receber a imagem ou vamos começar com o nome primeiro. Dentro do div, vamos exibir isso dentro da tag h1. Vamos interpolar o nome. Agora precisamos passar esse nome para cá. Ao mapear o componente show card, passarei name, equals data, show.name, algo assim. Vamos tentar ver. Na verdade, você pode ver que agora tudo é grande e ousado. Esta é a nossa tag h1. Em seguida, passaremos a imagem se inspecionarmos nossos dados de API. Vamos tentar ver. Temos a imagem do show. Uma imagem é um objeto com teclas médias e originais. Vamos tentar ver se esses dados mudam de alguma forma. Imagem, ainda temos algumas, mas posso dizer que a imagem aqui pode ser nula porque nem todos os programas que recebemos dessa API têm imagens. Eles podem não ter nenhum dado. Nesse caso, a imagem será nula. Como poderemos exibir algo? Para essas situações, o que eu sugiro fazer. Caso não recebamos nenhuma imagem da API, mostraríamos a imagem do espaço reservado para o usuário, algo como imagem não encontrada. Para isso, podemos voltar para o convidado que você compartilhou com você. Aqui você pode encontrar esse espaço reservado para shows, atores sem imagem de capa. Você pode clicar nessa imagem, clicar com o botão direito nela, salvar a imagem como e vamos colocá-la em nosso projeto. Vou colocá-lo dentro pasta pública e vou chamá-lo como image.png não encontrado. Ótimo. Se eu olhar para o público, agora ela apareceu aqui e podemos realmente nos referir a essa imagem PNG dentro do nosso código-fonte. Vamos ver rapidamente como fica. A fonte da imagem não será uma imagem vinculada porque nosso arquivo é colocado em público e é exibido pela rota do aplicativo. Nós o salvamos, voltamos ao aplicativo e sempre que procuramos programas, temos isso, perfeito. Essa é a imagem que temos. Agora, dentro da grade show, vamos passar image prop, mas vamos especificar se data.show.image é verdadeiro. Nesse caso, pegue este image.medium, data.show.medium, caso contrário , mostre não encontrado. Como o chamamos? Não foi encontrado image.png. Ótimo. Agora, dentro do cartão de exibição, podemos pegar esse suporte de imagem e exibir em algum lugar aqui em cima. Vamos encapsular a imagem em uma div. Então, a fonte será a imagem que distribuímos e divulgamos será o nome do programa. Vamos ver rapidamente o que temos. Temos algo errado aqui. Vamos ver, não temos nenhuma fonte. Por que isso? Tem que ser data.show.image.medium. Agora você pode ver que funcionou muito bem. Vamos tentar procurar atores, e você pode ver agora que temos todas essas imagens de capa. Bom. Vamos prosseguir e preencher os dados do aplicativo. O que mais precisamos mostrar? Gostaríamos de mostrar talvez apenas um resumo e o interior de cada cartão, mas também teremos um botão para começar esse show no futuro. Quando clicamos nesse botão, ele inicia e, quando clicamos no cartão, nos leva à página de exibição. Que criaremos no futuro. Dentro do cartão de exibição, precisaremos de um documento de identidade. Também precisaremos de um resumo. Vamos ver como podemos exibir tudo aqui. Vamos criar um div aqui. Um div provavelmente será um link por enquanto que importamos do [inaudível]. Dentro do link, diremos leia mais. O link nos levará, por enquanto, à rota. Não vamos fazer nada sobre isso por enquanto. Então, temos um botão aqui do tipo botão, que será estrelado por enquanto, no futuro, o substituirá pelo ícone. Sobre o resumo. O resumo que vamos exibir em algum lugar aqui e não o resumo, pois isso simplesmente não exibirá o suporte que recebemos, vamos transformá-lo de alguma forma. A razão por trás disso é que, se analisarmos a resposta da API, teremos a sequência de resumo. Mas, como você pode ver, é uma string HTML. Isso significa que podemos simplesmente pegar esse HTML e usar. O problema é que é bem longo. Queremos que seja breve. Não queremos exibir centenas de palavras aqui. Eu sugiro transformar essa sequência de resumo em algo muito curto. Vamos retirar todas as tags HTML daqui e vamos pegar apenas, digamos, as primeiras 10 palavras, provavelmente. Como podemos fazer isso? Suponha que recebamos essa string aqui. Vamos escrever a lógica dentro do console do navegador aqui. Temos essa corda aqui. Nessa string, primeiro vamos transformá-la em uma matriz chamando o método.split e vamos dividi-la por espaços vazios. Agora temos algo assim. Então, vamos pegar apenas os primeiros 10 elementos dessa matriz, .split depois disso, vamos cortar do índice zero para o índice 10. Acabamos com uma matriz de 10 elementos. Em seguida, vamos transformar essa matriz novamente em string. Vamos unir todos os elementos com uma string vazia no meio. Parece que sim. Mas ainda temos tags HTML aqui, então precisamos substituí-las. Vou mudar o método.replace disponível em todas as strings. Aqui, vou passar algo chamado expressão regular. Vou combinar todos os caracteres desnecessários e depois substituí-los por uma string vazia. Basicamente, isso apenas os eliminará. Não pense nisso para combinar. A expressão regular que vou escrever apenas substituirá todas as tags HTML dentro da nossa string atual. Ficará assim. Só não preste muita atenção nisso. Nosso resultado final ficará assim. Pegamos essa sequência de caracteres HTML, a encurtamos e removemos todas as tags HTML. Eu posso simplesmente copiar essa lógica. Eles acabaram de escrever aqui, e eu farei algo como um resumo retirado. Se eu não estiver errado, no resumo do programa também pode não estar presente, é por isso que vamos verificar valores falsos aqui. Se tivermos um resumo , chamaremos o método split e toda essa lógica para transformar nosso HTML em uma string simples, caso contrário, não contaremos nenhuma descrição. Em seguida, vamos exibir o resumo retirado. ID por enquanto não está sendo usado, mas vamos mantê-lo assim. Salvamos o arquivo, vamos para show grid novamente e passamos o ID, que será data.show.id e, por nome, já o temos. No final, vamos passar um resumo. Será bem simples, apenas data.show.summary. Eu sei que parece muito, mas confie em mim, essa é apenas uma forma normal de trabalhar com dados da API. De alguma forma, você precisa pensar como deseja que ele exiba os dados. Isso é apenas uma coisa normal aqui. Eu a guardo, volto aqui, e se eu procurar meninos dessa vez, onde estão meus meninos? Eles estão aqui. Agora eu tenho a sequência de resumo que transformamos com link Ler, bem como o botão Star Me. Bem, parece ótimo, não é? Agora, na verdade, passamos muito tempo em shows aqui. Vamos resumir rapidamente os atores que temos. Dentro da grade de atores, podemos simplesmente copiar essa lógica daqui. Não precisamos do log do console. Vou apenas copiar a lógica da grade de exibição colocá-la dentro da grade de atores. Receberei rapidamente o adereço do ator que passar aqui. Atores. Dados pop. Eu faço isso dentro do show grid. Eu preciso fazer isso dentro da grade de atores. Eu recebo atores aqui. Eu mapeio atores e os mapeio para o cartão de atores. ActorCard.jsx. Vou copiar essa lógica muito rapidamente do cartão de exibição, colocá-la dentro do cartão do ator. Vou renomear o cartão de apresentação para cartão de ator e, desta vez, quais dados receberei? Em primeiro lugar, os atores também têm nomes. Eles também têm imagens e também identidades, ou talvez não. Não precisamos de identificação porque teremos uma página separada para cada programa, mas não teremos uma página separada para cada ator. Precisaremos de um nome, precisaremos de uma imagem, provavelmente precisaremos de algo como sexo, país, talvez aniversário e dia da morte. Então, aqui dentro da grade de atores, vou usar esse cartão de ator aqui. Foi importado automaticamente em vez de passar por todos esses adereços. Deixe-me removê-lo. Para a chave, vou passar o ponto de dados, deixe-me realmente ver. O que temos aqui? Mostrar cartão não está definido. O resumo não está definido. Vá lá. Deixe-me procurar atores. Deixe-me ver a solicitação de rede. Aqui eu tenho uma pessoa. Isso é pessoa, então dados, pessoa. Pessoalmente, tenho aniversário, país nulo, dia da morte nulo, sexo nulo, mulheres. Você pode ver que já tem muitos nulos. Bem, isso não é ruim. Vamos passar o nome. Será apenas data person.name. Então será um país. Se eu não estiver bêbado, o país pode ser na verdade um objeto. É um objeto com nome aqui. Vou apenas passar dados, pessoa, país.nome. No entanto, o país pode ser nulo, então precisamos verificar isso. Se os dados, a pessoa o país forem verdadeiros, anote o nome. Caso contrário, por favor, dê nulo. Então, fazemos aniversário. Como você viu, o aniversário não pode ser nulo, mas vamos lidar com esse cartão interno de ator. Vamos passar dados, pessoa, aniversário. Então também temos o dia da morte, que é praticamente o mesmo que aniversário. Então também temos gênero. O gênero será dado, pessoa, gênero. Além disso, acho que esquecemos a imagem. Imagem, acho que será praticamente a mesma que com os shows. Vou apenas copiá-lo. Vou perguntar se existem dados, pessoas e imagens. Por favor, indique dados, pessoa, imagem, mídia, caso contrário, imagem PNG não encontrada. Ótimo. Agora, qual será a marcação da grade de atores? Deixe-me ver. A imagem permanecerá a mesma sem nome. Dentro de H1, ainda exibiremos o nome, mas ao lado do nome também exibiremos gênero entre parênteses, se houver algum. Podemos incorporar nossa lógica aqui. Você lembra que podemos embutir a renderização condicional diretamente dentro do JSX. Se o gênero estiver presente, exiba a string, que será entre parênteses e dentro dos parênteses, interpolaremos o gênero, e esse gênero pode ser nulo. Quando usamos o operador and para renderizar condicionalmente essa lógica, queremos sempre garantir que o gênero seja um valor booleano. É por isso que vamos transformá-lo em um booleano como esse para verificá-lo, ou podemos aplicar a negação dupla, que também o transformará em um valor booleano. Ao lado do nome, vamos exibir o país dentro da tag do parágrafo, eu acho. Vamos perguntar se o país é conhecido e, em seguida, exibiremos uma sequência que diz que vem do país. Caso contrário, não contaremos a nenhum país, a ninguém. Então temos aniversário e dia da morte. Vamos fazer a mesma lógica aqui. Se tivermos aniversário, um valor booleano. Por favor, exiba a tag p com nascido no aniversário. Provavelmente o mesmo para o dia da morte ou para o dia da morte, em vez de não mostrar nada quando acontece agora, ainda podemos dizer que essa pessoa está viva. É por isso que vamos criar a tag p aqui e vamos perguntar se temos o dia da morte, por favor. Display morreu neste dia da morte. Caso contrário, exiba ao vivo. Nós realmente não precisamos desse div na parte inferior. Nossa marcação final é assim. Não precisamos do componente de link na parte superior. Bem, isso foi muito e eu já estou cansado escrever toda aquela lógica bem chata de exibir dados. Mas ainda temos que passar por isso. Vamos procurar shows. Temos tudo sendo exibido. Agora, mudamos para atores. Vamos procurar Harry desta vez, não Gary, mas Harry. Aqui temos a imagem. Você pode ver se a imagem não existe, ela mostra a imagem não encontrada. Então temos o nome, o gênero entre parênteses. Então não temos nenhum país, ninguém vivo ou não vivo, quando a pessoa nasceu. Todos os dados que tivermos da API serão exibidos dessa maneira. Eu acho que é isso. Vamos comprometer tudo e seguir em frente. Eu vou cometer tudo. Eu sei que você viu este aviso que temos por causa dessa identidade. Isso é bom. Vamos mantê-lo lá por enquanto. Vamos lidar com isso mais tarde. Vamos comprometer tudo e divulgar os programas exibidos e os dados dos atores. Vamos pressionar tudo para dominar e fazer uma pausa. Eu vou te ver na próxima. 69. 13 Páginas com conteúdo dinâmico: Olá. No último vídeo, criamos cartões para shows e atores. Desta vez, falaremos sobre páginas dinâmicas. Como você se lembra em cartões para shows, temos aquele link para ler mais. Se voltarmos à marcação, esse é o componente de link que usamos do React Router dom. Por enquanto, ele vai para a página inicial até a raiz. Basicamente, ele não faz nada se clicarmos nele. Agora, o que queremos fazer em vez disso, ao clicarmos em “Leia mais”, devemos ser direcionados para a página específica do programa. Em primeiro lugar, precisamos decidir exatamente como nossa página do programa será representada. Nesse caso, e na maioria das vezes, as páginas são representadas por IDs. Temos ShowID. Pode ser nosso identificador exclusivo para a página, portanto, sempre que clicarmos em uma página no URL, alguma forma veremos showID. Podemos considerar duas opções aqui. Primeira opção, nosso URL será parecido com uma barra e, em seguida, o ID do show será fornecido como parte da string de consulta. Algo parecido com isso. Segunda opção que podemos considerar, em vez de fornecer Id como parte da string de consulta, podemos realmente transformar showId em segmento de URL. Eventualmente, a página de exibição terá um URL, algo como slash show, slash showId, e esse ID será alterado com base no programa em que clicamos. A questão aqui é como isso pode ser feito com o React Router. Se voltarmos ao componente do aplicativo aqui, como você se lembra, comentei a marcação que retirei da documentação para referência futura. Aqui temos essas equipes de rota e dentro delas temos algo com dois pontos, temos o ID da equipe de dois pontos. Tudo o que você vê aqui é algo chamado parâmetro de URL dinâmico ou segmento de URL dinâmico, porque é algo que muda. Todos os nossos dados que temos em nosso aplicativo são dinâmicos, porque o que quer que digitemos na entrada , eles serão dinâmicos. Não podemos realmente prever quais dados devemos esperar da API. Precisamos pensar de alguma forma em como podemos escrever o esqueleto para os dados dinâmicos. O que eu sugiro fazer é considerar a segunda opção que acabei de mostrar, e nosso URL será parecido com slash show, slash showId. Esse parâmetro dinâmico de URL showID é o que você vê aqui neste exemplo com dois pontos. Damos a ele algum nome, digamos TeamID. Especificamos que esse parâmetro nomeado será algo dinâmico que podemos extrair do URL. No nosso caso, o que podemos fazer aqui criar outra rota e criá-la fora do layout principal porque, para a página de exibição, não usaremos principalmente a rota que criamos anteriormente. Essa rota terá path slash show, slash, colon showId. Esse segmento dinâmico de URL aqui, eu dei o nome de ShowID. Eu terei o parâmetro de URL, que será dinâmico, e terá o nome ShowId. Para essa rota, eu gostaria de exibir a página de exibição. Vamos seguir em frente e criar um. Em páginas, vou criar outro componente chamado show, outro arquivo chamado show, e a marcação por enquanto será muito simples: mostrar página dentro do aplicativo. Vou importar esse componente de exibição da página e vamos tentar. Se eu navegar até a barra, mostrar, cortar alguma coisa, você verá que eu tenho a página de exibição. Na verdade, funciona. React Router conseguiu combinar esse caminho e me renderizar o componente show. Se eu for apenas mostrar, eu encontrei, não encontrei, porque apenas mostrar sem segmento de URL dinâmico não corresponderá a essa definição de rota. É por isso que ele volta para, não encontrado. Mas assim que eu for mostrar alguma coisa, terei a página de exibição. Ótimo. Agora, a questão é: como podemos, de alguma forma, recuperar esse showID do URL aqui e usá-lo dentro do nosso componente show. Nossa estratégia será a seguinte. Sempre que navegamos até a página de exibição e temos showID no segmento de URL dentro de nosso componente, podemos pegar esse segmento de URL, podemos pegar esse showID e usá-lo dentro do componente para consultar a API TVMaze e obter dados de exibição. Essa é uma abordagem muito comum quando você lida com páginas dinâmicas. Você terá uma parte dinâmica dentro do URL e, sempre que navegar até essa página, você pega essa parte dinâmica do URL e a usa dentro do componente para consultar dados. No nosso caso, isso será showID. Agora, como podemos extrair esse showID do URL? Se voltarmos à documentação do React Router, à esquerda temos o menu. Podemos rolar para baixo até a seção de ganchos e aqui estaremos interessados no gancho de parâmetros de uso. Você pode ler essa descrição rápida aqui para que use params hook retorne um objeto, pares de valores-chave dos parâmetros dinâmicos do URL atual que corresponderam ao caminho da rota. Vamos tentar isso. Você pode ver que ele foi importado do React Router dom. Eu farei exatamente o mesmo. Vou copiar isso muito rapidamente. Eu não preciso de rota, então eu só preciso usar parâmetros e dentro de Show, vou chamar use params. Vou criar uma nova variável chamada params. Por enquanto, vou simplesmente cancelar parâmetros de registro e ver o que eu tenho. Eu vou para o navegador para cancelar aqui, e aqui você pode ver que eu tenho um objeto em que showId é igual a tudo o que eu forneço na URL. Essa chave aqui corresponderá nome do parâmetro que demos a esse segmento de URL dentro da definição da rota. Se colocarmos aqui algo como, sei lá, muito aleatório, eu atualizo a página, você pode ver agora as principais mudanças. Eu especificamente dei a ele algo significativo, como showId, para que mais tarde possamos acessar esse showID dinâmico usando o gancho use params. Como vai ser um objeto, podemos usar essa estruturação. A partir desse objeto de parâmetros, vou pegar ShowID. Vamos tentar interpolar isso dentro do nosso JSX aqui. Mostrar página para showID. Vamos tentar e percebi que meu aplicativo não está salvo, deixe-me salvá-lo. Você pode ver a página de exibição para mostrar tudo o que eu coloquei no URL. Se foi exibido com Id1, eu tenho para, Show 1. Assim, agora criamos uma página dinâmica que representará nosso programa. Há mais uma coisa nisso. Não vamos alterar o URL dentro da caixa de pesquisa do navegador manualmente o tempo todo, não é? Precisamos modificar o link que temos dentro do cartão de exibição. Na verdade, isso nos leva a essa página dinâmica. Vamos tentar fazer isso. Dentro do show, sabemos que, para atributos, para adereços, podemos fornecer valores dinâmicos usando JavaScript. Em vez de apenas passar uma raiz de string estática, podemos abrir colchetes. Podemos dizer, por favor, vá para a barra, mostre o ID da barra e pronto. Vamos tentar ver isso. Se procurarmos olá, e sempre que eu passar o mouse sobre o link no canto inferior esquerdo, você poderá ver a barra do URL mostrar, cortar cinco e algo. Sempre será diferente para cada show. Se eu clicar nele e navegar até a página, deixe-me voltar e clicar em outra coisa . Você verá que agora é diferente. Assim, podemos criar páginas dinâmicas dentro do nosso aplicativo com o React Router dom, e podemos pegar parâmetros dinâmicos do URL usando o gancho use params e, em seguida, você os usa dentro do componente para buscar dados. Vamos fazer isso no próximo vídeo. Por enquanto, vamos comprometer tudo o que fizemos aqui. Vamos dar uma visão geral. aplicativo Insight, criamos uma nova multidão dinâmica , baseada no parâmetro showID. Chamamos esse parâmetro de showID. Dentro do componente Show que criamos e esse componente representa nossa página, pegamos o parâmetro showId, usando o gancho use params. Dentro do cartão curto, modificamos o link para realmente nos redirecionar para a página do programa. Incrível. Vou nomear tudo como página de exibição dinâmica criada, e acho que tudo ficará bem, envie tudo para o GitHub e nos vemos na próxima. 70. 14 Introdução ao gancho useEffect: Olá. No último vídeo criamos uma página de exibição dinâmica. Agora é a hora de buscarmos alguns dados dinâmicos nessa página. Neste vídeo, vamos falar sobre as formas como isso pode ser alcançado. Para entendermos como funciona, precisamos conhecer outro gancho do React chamado useEffect. Anteriormente, você lembra que conversei com alguém sobre o ciclo de vida dos componentes. O ciclo de vida do componente é o período de tempo desde a montagem do componente até ser desmontado da página. Vamos examinar mais de perto o ciclo de vida dos componentes. Podemos diferenciar três pontos de tempo diferentes quando o componente é montado. A segunda é quando o componente já está montado e é renderizado novamente toda vez que o estado interno muda. Uma nova renderização e o terceiro ponto no tempo serão desmontados ou apenas quando o componente for desmontado. Esses três pontos no tempo representam o ciclo de vida do componente. Para nossa estratégia de busca de dados, estamos interessados apenas no momento em que o componente é montado. Porque nossa lógica será a seguinte. Assim que abrimos a página dinâmica para exibição, pegamos o ID de exibição do URL e, em seguida, usamos esse ID de exibição para buscar dados apenas uma vez quando o componente é montado. Não queremos executar novamente essa lógica de busca de dados toda vez que lógica de busca de dados toda vez componente for renderizado novamente. Isso é importante para entender que precisamos executar a lógica apenas uma vez. Agora vamos tentar ver como o UseEffect Hook pode nos ajudar a conseguir isso. Provavelmente, deixe-me navegar até o formulário de pesquisa. Neste componente, vamos brincar com esse UseEffect Hook e entender como ele funciona e como pode nos ajudar. Vou colocar esses três pontos sobre o ciclo de vida do componente aqui. Então, no topo do React, vou importar useEffect. Agora, vamos tentar usar esse gancho. Dentro do componente, vou chamar esse gancho, e esse gancho recebe dois argumentos. O primeiro argumento é a função, o retorno de chamada que executará a lógica que queremos e o segundo, argumento, é algo chamado de matriz de dependências. Falaremos sobre a matriz de dependências um pouco mais tarde. Por enquanto, vamos passar uma matriz vazia. Agora, nosso primeiro caso de uso será quando o componente for montado. Queremos executar a lógica apenas uma vez quando o componente é montado. A propósito, esse retorno de chamada é chamado de efeito do useEffect. Vamos nos referir a esse retorno de chamada como o efeito. Meu efeito será que vou apenas executar o log do console e dizer montagens de componentes. Nada complicado. Agora vamos voltar ao nosso aplicativo, abrir o console e, dentro do console, vemos montagens de componentes, impressas duas vezes. Ele é impresso duas vezes porque temos o modo estrito do React. Se você se lembra do desenvolvimento, intencionalmente, isso equivale a um componente duas vezes para detectar possíveis erros. Não queremos esse comportamento quando trabalhamos com useEffect. Por enquanto, vou apenas remover o modo estrito do React. Vamos voltar ao nosso aplicativo. Quando eu atualizo a página e o componente é montado, o componente do formulário de pesquisa é montado, vejo meu registro do console aqui. Se eu tentar atualizar um desses estados, se eu digitar algo na entrada, componente será renderizado novamente. Mas você verá que as montagens de componentes nunca mais serão executadas. Deixe-me tentar. Eu digito algo na entrada, esse componente é renderizado novamente. No entanto, as montagens de componentes nunca mais funcionarão. Para tornar a observação mais fácil , aqui, vou adicionar o log do console e dizer que o componente renderiza novamente. O que temos aqui? Suportes de componentes. Vemos a renderização do componente novamente. Isso é bom porque é a primeira vez que o componente é montado. Então, na verdade, vemos a mensagem que usamos dentro de useEffect. Agora, se eu atualizar esse estado, você só verá o componente renderizado novamente. Nunca vemos montagens de componentes. Assim, podemos executar a lógica apenas uma vez quando o componente é montado. Agora, vamos observar o terceiro caso de uso aqui. Quando o componente é desmontado. Em useEffect dentro desse efeito, dentro do callback, você pode passar algo chamado função de limpeza. É basicamente a função que retornada do retorno de chamada. Função de retorno. Esta função aqui será executada quando o componente for desmontado. Vamos tentar ver. Dentro da função de limpeza, vou escrever componentes desmontados. Vamos ver. Primeiro, temos exatamente o mesmo comportamento de antes. Mas assim que eles mudarem a página, a navegação, se eu for para a página inicial, esse formulário de pesquisa de componentes será desmontado da página. Vamos ver o que acontece. Vou começar e você vê componentes desmontados. A lógica definida dentro da função de limpeza será executada logo antes de o componente desmontado da página. Dessa forma, podemos nos conectar ao ponto desmontado no tempo. Até agora, calculamos dois momentos em o componente é montado e quando o componente é desmontado. Com o segundo caso de uso, quando o componente é renderizado novamente , fica um pouco complicado com useEffect. Digamos que eu gostaria de executar alguma lógica, sempre que a opção de pesquisa mudar. UseEffect é capaz de executar alguma lógica quando algo muda. Esse segundo argumento, a matriz de dependências, serve exatamente a esse propósito. Ele define e instrui o useEffect a executar essa lógica a partir do callback quando algo muda. Dentro da matriz de dependências, listamos os valores que gostaríamos de ouvir e, quando esse valor muda, instruímos useEffect, execute novamente a lógica. Vamos experimentar e ver. Vou comentar sobre a função de limpeza Em vez de montagens de componentes, contarei algo como mudanças nas opções de pesquisa. Como matriz de dependências, como um dos valores dentro da matriz de dependências, passarei a opção de pesquisa. Vamos ver. Eu atualizo a página, nada é impresso porque atualmente estou na página inicial. Assim que eu vou para a página inicial, vemos uma nova renderização de componentes e mudanças nas opções de pesquisa. Por que vemos mudanças nas opções de pesquisa quando especificamos algo dentro da taxa de dependência? O fato é que o useEffect sempre é executado pelo menos uma vez, não importa o que aconteça. UseEffect é executado pelo menos uma vez, não importa o que aconteça. Agora, se eu tentar digitar algo dentro da entrada, veremos apenas a renderização do componente novamente, nunca veremos alterações nas opções de pesquisa. Mas assim que eu atualizar o estado das opções de pesquisa chamando set search option, o useEffect será executado novamente. Vamos ver. Vemos mudanças nas opções de pesquisa. Nós o alteramos novamente e, toda vez que o valor é alterado, o efeito é executado novamente. simples quanto isso. Aqui, você pode listar quantas dependências quiser. Se um deles mudar, o efeito será repetido toda vez. Basicamente, ouvimos mudanças de valor e, se essa mudança de valor ocorrer, o efeito será repetido. Usando esse método, podemos nos conectar à lógica de renderização do componente e executar nossa própria lógica aqui usando, novamente, o gancho useEffect. No entanto, vamos chamá-lo de caso de uso 2.5, quando queremos executar a lógica antes da próxima renderização. Pode parecer sofisticado, e até certo ponto é, mas vamos ver como funciona. Nosso 2.5 será lógico antes das próximas três renderizações. A função de limpeza aqui, eu disse anteriormente, se você quiser executar alguma lógica antes da quantidade do componente, você pode retornar essa função a partir do efeito e tudo o que você colocar dentro será executado antes que o componente seja desmontado. No entanto, isso só funciona quando a matriz de dependências está vazia. Se tivermos dependências dentro da matriz de dependências, a função de limpeza será executada para cada efeito. Quando o efeito atual terminar, a lógica será executada para esse efeito antes que o próximo efeito seja executado. Em vez de quantidades de componentes, digamos que a opção de pesquisa mude, e aqui dentro do mesmo log do console, também vamos colocar a opção de pesquisa. Poderemos ver o valor do estado. Vamos tentar. Eu atualizo a página. Vejo mudanças nas opções de pesquisa. Atualmente, mostra. Assim que eles mudarem a opção, vamos ver o que acontece. Vemos a renderização do componente como de costume, vemos mudanças nas opções de pesquisa. Digamos que seja a opção de pesquisa, digamos, antes da próxima opção de pesquisa ser alterada ou, digamos, antes da próxima execução do useEffect. Vamos tentar novamente. Vemos mudanças nas opções de pesquisa, shows. Agora mudamos a opção, e o que eu vejo antes da próxima execução de UseEffect, vemos shows. Essa função de limpeza é executada para cada execução de efeito. Nossa atual corrida aqui nesse sentido é para atores estatais. Como nosso estado atual é de atores, é quando ocorre o último efeito. Da próxima vez que o efeito for executado, a função de limpeza será executada para nosso efeito atual para atores. Se eu mudar para shows novamente, veremos antes da próxima execução do UseEffect com atores e, em seguida, veremos mudanças nas opções de pesquisa com shows. Vamos tentar. Vemos antes da próxima execução de useEffect, na verdade, a partir de agora nossa execução anterior de useEffect e nossa nova execução de useEffect. Bem, parece complicado. Na verdade, à primeira vista, é. No entanto, isso realmente faz sentido. Há muitos casos de uso em que você deseja usar cada uma dessas opções. Ao usar o useEffect, podemos executar alguma lógica durante o ciclo de vida competente sob diferentes condições e circunstâncias. Podemos usar a matriz de dependências para instruir useEffect quando quisermos executar essa lógica. No momento, analisamos useEffect e registramos o valor do estado das opções de pesquisa sempre que uma opção de pesquisa muda. Você pode ter uma pergunta: por que usamos useEffect aqui se podemos simplesmente colocar o log do console diretamente aqui sem useEffect, assim como fizemos com a renderização de componentes novamente. Bem, o fato é que, com useEffect novamente, você tem a matriz de dependências. Essa nova renderização do componente de log do console será executada em todas as renderizações competentes, não importa o que aconteça. O componente é renderizado, você sempre verá esse log do console. No entanto, com o useEffect, você escuta somente valores que mudam, e esses valores são especificados dentro da matriz de dependências. Se você especificar uma matriz de dependências vazia, esses useEffect serão executados apenas uma vez quando o componente for montado. Essa lógica, a função de limpeza aqui será executada quando o componente for desmontado. Mesmo se você tiver a dependência, quando o componente for desmontado, você verá que a função de limpeza também será executada. Vamos observar isso. Mudamos de ator e temos nossa execução antes da próxima execução do UseEffect. Quando o componente for desmontado, você verá antes da próxima execução do UseEffect. Basicamente, a função de limpeza, como eu disse, limpa a execução atual do UseEffect. Usando essa abordagem, podemos buscar dados apenas uma vez quando o componente é montado. Vamos especificar uma matriz de dependências vazia para instruir o useEffect a ser executado apenas uma vez quando o componente for montado. Dentro do efeito, vamos buscar a lógica da API. simples quanto isso. Agora que conhecemos um pouco mais sobre o ciclo de vida competente, agora sabemos que podemos usar o useEffect para manipular a lógica competente durante o ciclo de vida do componente, podemos buscar dados e finalmente exibir algo. No próximo vídeo, faremos exatamente isso. Por enquanto, vamos recuperar o modo estrito de reação e falaremos sobre isso mais uma vez. Por enquanto, é isso. Eu vou te ver na próxima. 71. 15 dados da API do labirinto da TV com o useEffect: Olá de novo. No último vídeo, falamos sobre o UseEffect Hook, como ele pode nos ajudar a manipular a lógica dentro do componente durante o ciclo de vida do componente. Vamos tentar aplicar useEffect em nossa página de exibição dinâmica para buscar alguns dados. Vamos embora. Eu vou para páginas, Show.jsx. Aqui, como você se lembra, pegamos o showID do URL. Vamos procurar shows. Digamos, meninos. Vamos ler mais. Nós temos esse URL. O que quer que tenhamos no URL, nosso parâmetro dinâmico, nós o capturamos usando o gancho useParams. Agora, vamos importar o useEffect do pacote React, e agora dentro, o que fará o useEffect. Como queremos buscar dados apenas uma vez, queremos executar a lógica apenas uma vez quando o componente é montado. Por esse motivo, especificamos uma matriz vazia de dependências. Dentro desse useEffect, buscaremos Data. Vamos ver como será a aparência do endpoint. Isso nos dará informações sobre o show. Se acessarmos a API TVMaze e procurarmos a seção de programas aqui, teremos esse endpoint/shows/id, e você poderá ver este exemplo. Vamos abri-lo e ver. Ao fornecer o ID do programa, poderemos obter todos os dados necessários. Vamos criar outra função reutilizável dentro do tvmaze.js, onde consultamos esse endpoint. Vamos explorar outra função a partir daqui que chamaremos de getShowById. Como argumento, vamos especificar showID e, internamente, chamaremos ApiGet e chamaremos esse URL de ponto final. Como o ID é algo dinâmico que fornecemos por meio do argumento, usaremos acentos invertidos para podermos aplicar a interpolação de strings. Nossa função ficará assim. Agora, dentro do show jsx, podemos importar getShowById da API TVMaze. Então, dentro de useEffect, poderemos chamar getShowId e passar showId para dentro. Gostaríamos de usar uma sintaxe de espera de sincronização porque ela é mais fácil de usar, mas você não pode tornar o retorno de chamada de useEffect assíncrono. Se eu fizer isso, você verá este aviso aqui, que vem desta regra de regras de ganchos da ESLint. Diz que os retornos de chamada de efeito são síncronos para evitar condições de corrida, coloque a função assíncrona e o site. Você pode ver esse exemplo aqui. Bem, vamos fazer exatamente isso. Vamos criar uma função assíncrona dentro de useEffect e depois chamar essa função interna. Vamos tentar isso. No nosso caso, será parecido com FetchData. Não marcamos o retorno de chamada como assíncrono, que é chamado de fetchData. Dentro de fetchData, chamaremos um peso de ser exibido por ID e forneceremos showID que extraímos do URL. Agora, assim que eu usar showId dentro de useEffect, você notará que agora eu tenho este aviso aqui que diz: gancho do React useEffect tem uma dependência ausente, showId. Se você tem algo definido dentro do componente e usa esse algo, esse valor dentro de useEffect, idealmente, ele deve ser especificado como a dependência desse useEffect. A razão para isso é porque digamos nosso showId aqui também possa ser dinâmico, por exemplo, pode ser nosso estado, e queremos executar esse useEffect sempre que esse valor mudar. Se não fornecermos nenhuma dependência aqui, mantenha nossa matriz de dependências vazia, a lógica será executada apenas uma vez quando o componente for montado. Mas e se esse showID mudar, digamos, de 1 a 2? Nesse caso, faz sentido atualizarmos os dados para pegar o último programa com ID igual a dois. Mas se mantivermos a matriz de dependências vazia, o efeito nunca mais será executado. Para que possamos corrigir isso, tudo o que usamos dentro de useEffect, todos os valores aqui que podem ser potencialmente dinâmicos ou mudar, precisamos especificar isso. Essa é nossa dependência desse retorno de chamada useEffect. É por isso que vou listar showID como parte do useEffect. Agora, obtemos nossos dados aqui. Vamos testar os dados de registro do console. Nós voltamos aqui. Agora, o que vemos, vemos dois registros do console. Novamente, a razão para isso é o StrictMode que temos. StrictMode é problemático e foi introduzido na versão 18 do React, mas agora você pode ver que temos esse problema no desenvolvimento de que o componente é renderizado novamente duas vezes. Como buscamos dados dentro de useEffect, isso significa que buscamos dados duas vezes. Isso não é realmente o que queremos. Nesse caso, a equipe do React recomenda que, a partir do React 18, se você quiser buscar Data, use outra coisa em vez de useEffect. Vamos falar sobre isso um pouco mais tarde, no entanto, isso é muito controverso. Antes do React,18 na versão 17 e anteriores, a maneira mais básica e padrão de fetchData era exatamente isso, usando useEffect. Bem, com o React 18, nada muda muito, exceto que agora temos o React StrictMode. Por enquanto, sugiro que removamos o React StrictMode e o ativaremos mais tarde, quando veremos uma alternativa ao uso do useEffect Hook para fetchData. Por enquanto, dentro do índice jsx, vou remover o React StrictMode. Nosso useEffect não será executado duas vezes no desenvolvimento. Agora, vamos salvá-lo. Eu atualizei a página e veja, eu tenho dados aqui. Se eu abrir a guia Rede, eu atualizo a página. Aqui, posso encontrar a chamada para a API TVMaze com showID que recebemos do URL. Se eu pré-visualizar, esses são os dados que temos. Agora, vamos criar um estado e colocar esses dados dentro do estado. Vamos chamá-lo apenas de showData e definir show data. Essa será a chamada useState. Por padrão, os dados serão nulos. Em seguida, vamos criar outro estado para detectar qualquer erro caso a solicitação falhe. Vou criar ShowError, setShowError. Por padrão, as chamadas são nulas. Vou encapsular uma maneira de getShowId, getShowById no bloco try catch. Dentro do bloco catch, chamarei set showError como null. Então, quando recebo dados, chamo setShowData e defino esses dados como parte do estado. Agora, aqui podemos usar a renderização condicional para exibir quaisquer dados que coletamos e poderemos usar o estado ShowData. Podemos escrever a lógica de renderização condicional diretamente dentro do componente, não apenas dentro da marcação JSX, não apenas usando, digamos, uma função auxiliar na qual definimos lógica, mas também podemos escrevê-la diretamente dentro do componente. Aqui, vou perguntar, se tivermos showError dessa função, do nosso componente, retorne div, que diz que temos um erro, que será showError.message, porque showError será o objeto de erro. Aqui eu o defino como nulo, desculpe, tem que ser o outro objeto que capturamos aqui. Agora, caso tenhamos um erro, retornamos a marcação JSX com erro. Se tivermos showData, neste caso, obtemos os dados do show. Por enquanto, vamos cancelar. Vamos ver. O que nós temos? Temos um nome, então seja o nome ShowData. Por padrão, se nenhuma dessas duas condições for mantida, podemos dizer que os dados estão sendo carregados. Eu posso ver que não usei a pesquisa ShowError. Aqui, eu realmente não o usei. Vamos ver. Tenho que mostrar dados, garotos. Quando eu atualizo, você pode ver isso piscando aqui, e esse piscar é que esses dados estão carregando. Os dados são carregados tão rápido que nem percebemos que os dados estão carregando a mensagem. Mas se essa chamada de API demorasse, digamos, 10 segundos, veríamos que os dados estão sendo carregados. Usando essa abordagem, você pode buscar dados quando o componente é montado. No próximo vídeo, apresentaremos um novo termo para nós, chamado React Hooks personalizados. Por exemplo, aqui, costumávamos usar UseState e usamos useEffect e useParams. O que quer que você importe diretamente do React, esses ganchos são chamados de React Hooks integrados. Mas você pode ver em react-route-dom que importamos algo chamado useParams. Também é um React Hook, mas não faz parte da biblioteca React. É algo personalizado que foi criado pelo react-router-dom. No próximo vídeo, falaremos sobre isso e criaremos nosso próprio gancho personalizado. Mas antes de terminarmos esse vídeo, vamos confirmar tudo o que fizemos. Em primeiro lugar, desativamos o StrictMode, portanto, no desenvolvimento, nosso useEffect não será executado duas vezes. Em seguida, criamos uma função getShowById que busca dados e dentro do componente show, usando o gancho useEffect, o fetchData. Git add dot commit everything. Vamos contar fetchData dentro do componente show ou buscar mostrar dados dentro do componente show, sem mais nem menos. Próximo vídeo, ganchos personalizados. Te vejo lá. 72. 16 ganchos de reação personalizados: Ei, aí. No último vídeo, buscamos dados dentro do componente show com a ajuda de useEffect. última vez, mencionei que, neste vídeo, falaremos sobre a diferença entre ganchos de reação integrados e ganchos personalizados que podemos importar de outras bibliotecas. O fato é que esses ganchos personalizados são, na verdade apenas mais lógicos do que ganchos de reação integrados que você já viu, como useEffect ou useState. Qual é a diferença então? Esses ganchos useParams, por exemplo, são apenas ganchos com lógica extra, então não precisamos escrever essa lógica dentro do componente. A questão está aqui por que precisamos de ganchos personalizados? Você pode ver que, no último vídeo, usamos três ganchos diferentes, na verdade dois ganchos, mas os usamos três vezes dentro do nosso componente, useState, useState e depois useEffect aqui. Agora, digamos que eu queira reutilizar essa lógica dentro de outros componentes. Qual é a minha opção então? Uma abordagem muito ingênua é simplesmente copiar esse trecho de código e usá-lo em algum lugar dentro de outros componentes. Mas você pode ver que é muita repetição. Se não falarmos especificamente sobre reagir, se pudermos ver o exemplo de programação para reutilizar a lógica de alguma forma, usamos funções ou se quisermos apenas extrair algo do local, também usaríamos uma função para não colorir o espaço onde essa lógica está presente. Exatamente o mesmo se aplica aos ganchos. Se você quiser reutilizar a lógica dos ganchos, ou se quiser apenas extrair a lógica do componente, você pode colocá-la dentro de um reator personalizado. Essa é a razão pela qual os usamos. Eles são usados para reutilizar a lógica dos ganchos e segunda opção é quando você deseja extrair a lógica do componente para que não ocupe muito espaço dentro desse componente. Em nosso caso, essa lógica não será reutilizada em nenhum lugar do aplicativo porque temos apenas um local onde buscamos show específico dentro do componente show. Mas vamos imaginar que tivéssemos outro lugar onde queríamos buscar esses dados do programa. Em vez de copiar e colar a lógica, poderíamos colocá-la em um gancho personalizado dentro de todos os componentes em que precisamos buscar esse programa. Deixe-me mostrar o que quero dizer. No topo do arquivo, vou criar um gancho personalizado de função que chamarei de algo como useShowById. Você pode dar o nome que quiser. Mas todos os ganchos de reação têm convenção de que devem começar com o prefixo de uso. Se você quiser nomear seu gancho personalizado, certifique-se de que ele comece com use, useShowById . Será apenas uma função simples e vou apenas copiar minha lógica para fetchData do componente para o gancho useShowById. Você pode ver algumas coisas aqui. Em primeiro lugar, dentro do gancho, não temos acesso à variável showID. Mas, como é uma função, podemos recebê-la como argumento. Vamos fazer isso. Você pode ver que dentro do componente show, agora, não temos nenhum acesso a showError ou ShowData. Exatamente a mesma abordagem. Se nosso useShowById for apenas uma função, poderemos retornar algum valor dela. Vamos dizer que retorna um objeto com duas chaves, ShowData e ShowError. Agora podemos usar esse gancho useShowById dentro do componente show. Simplesmente chamamos esse gancho interno, passamos showId e esse gancho nos retorna um objeto com duas chaves, showData e ShowError. Vamos desestruturá-los. Agora, veja nosso resultado final. Temos apenas uma única linha e a lógica está escrita em outro lugar. Se eu esconder isso, você pode ver agora nosso componente está muito mais limpo do que era antes, e nossa lógica de buscar dados para buscar o show está em outro lugar. Agora, se eu quisesse reutilizar essa lógica em outros componentes, simplesmente chamaria useShowById, pass, showId como argumento e, em seguida, receberia meu ShowData e meu ShowError, por exemplo, vamos copiar esta linha. Se eu quisesse buscar show dentro do componente do aplicativo, eu usaria esse gancho no passado, qualquer programa que eu quisesse, como argumento e terei acesso a ShowData e ShowError. A lógica com ganchos personalizados, a ideia com ganchos personalizados é a mesma das funções na programação, mas com ganchos personalizados, você escreve lógica sobre ganchos embutidos ou outros ganchos de reação. simples quanto isso. Agora é isso. Mas você lembra que no último vídeo, quando introduzimos o gancho useEffect, tivemos esse problema com modo estrito de reação no desenvolvimento. O modo estrito de reação renderiza o componente duas vezes. É por isso que nosso useEffect sempre é executado pelo menos duas vezes. Isso foi problemático. A solução que a reação recomenda é usar outra coisa em vez de useEffect. No próximo vídeo, falaremos sobre isso. Vamos falar sobre a alternativa ao useEffect para buscar dados. Finalmente, poderemos recuperar nosso modo estrito do React e não teremos problemas em buscar dados apenas uma vez quando o componente for montado. Por enquanto, vamos nos comprometer com tudo e terminar este vídeo com uma boa nota, como sempre. Minha mensagem de confirmação será muito simples: extraia a lógica de agrupamento de dados em um gancho personalizado useShowById. Incrível. Nos vemos na próxima. 73. 17 Dados obtendo com bibliotecas: Olá de novo. No último vídeo, falamos sobre a diferença entre React integrados e ganchos React personalizados. Basicamente, ganchos React personalizados são os ganchos que escrevemos com nossa própria lógica em cima dos ganchos React integrados. A razão por trás disso é que queremos extrair alguma lógica, ou se queremos tornar a lógica dos ganchos reutilizável. Nesse caso, usamos ganchos personalizados. Também buscamos dados da API TVMaze apenas uma vez quando o componente é montado. Fazemos isso com a ajuda do gancho useEffect. Mas se você se lembrar, desabilitamos o React StrictMode porque ele força o componente a ser renderizado novamente duas vezes no desenvolvimento, o que significa que useEffect sempre será executado pelo menos duas vezes em vez de apenas uma vez. Isso é problemático para nossa situação específica e, para evitar isso, a equipe do React recomenda buscar dados com outra coisa. Eles não recomendam usar o gancho useEffect para buscar dados quando você tem o React StrictMode ativado. Eles falam sobre outra coisa. O que é isso? Bem, no front-end, existe o conceito de algo chamado bibliotecas de busca de dados. Dois exemplos aqui podem ser React Query e usar SWR; ambos são muito populares e são muito semelhantes entre si. Mas o que eles realmente fazem, por exemplo, na página de uso de SWR, podemos ver aquele exemplo muito simples com o qual chamamos de gancho use SWR, digamos, o caminho que queremos buscar e, em seguida, a função que busca dados. Em seguida, o gancho nos dá um erro de dados que podemos usar em nosso aplicativo. Agora, se compararmos isso com o que escrevemos aqui, você pode encontrar uma nota muito semelhante, no entanto, nosso gancho aqui é voltado especificamente buscar programas da API TVMaze e buscá-los por ID. Portanto, essa é a lógica específica que está fortemente acoplada à API TVMaze para buscar o programa especificamente por ID. Se tivéssemos, digamos, muitas lógicas de busca diferentes dentro de nosso aplicativo em centenas de componentes, nesse caso, teríamos que criar algo mais abstrato para tornar nossa lógica de busca mais reutilizável e não fortemente acoplada a uma implementação específica. As bibliotecas de busca de dados fazem exatamente isso; elas nos fornecem o gancho abstrato que podemos usar para buscar dados dentro do componente. Portanto, é mais fácil reutilizar essa lógica em todo o aplicativo que escrevemos, que criamos. Por exemplo, no React Query, vamos encontrar o Quick Start. Você pode ver que a lógica é muito semelhante; temos algo chamado chave de consulta e função de consulta, vamos falar sobre isso em um segundo, mas a lógica é a seguinte. Temos um gancho abstrato para buscar dados, para esse gancho abstrato, fornecemos nossa lógica para buscar dados, e esse gancho personalizado nos dá um erro de dados e está carregando variáveis que podemos usar dentro do componente. Eles existem para tornar a busca de dados mais otimizada, mais reutilizável e mais fácil de usar para os desenvolvedores. Vamos tentar instalar uma dessas bibliotecas. No nosso caso, vamos usar a consulta React, só porque eu decidi assim. Se você quiser, pode experimentar o UseSWR, a sintaxe é muito semelhante. Dentro da documentação, vou para a página de instalação. A partir daqui, vou apenas copiar o tanstack/react-query instalado pelo NPM. Vou adicionar essa dependência ao meu projeto. Ele aparecerá dentro do pacote Jason aqui no topo. Ótimo. Agora vou para o Quick Start e seguir o exemplo. Primeiro, precisamos criar um cliente, depois precisamos usar algo chamado provedor de clientes de crédito e passar esse cliente para lá. Então, dentro dos componentes, podemos usar o gancho useQuery. Vamos ver como isso pode nos ajudar. Vou copiar essas entradas daqui, vou para o componente do aplicativo aqui, no topo, vou importar apenas o vou importar cliente de consulta e o provedor crítico do cliente, assim mesmo , depois criarei um novo cliente de crédito fora do componente, depois usarei o provedor do cliente de crédito, digamos, em algum lugar aqui e o fecharei no final. Eventualmente, meu aplicativo agora tem essa aparência. Ótimo. Agora posso ir para a página de exibição e, em vez de usar o gancho use show by ID, usaremos o gancho useQuery aqui. Vamos comentar o que temos aqui, vamos chamar useQuery, que também pode ser importado de tanstack/react-query. Vamos fazer isso. Só precisaremos useQuery e, dentro do componente, chamaremos useQuery assim. Agora precisamos passar as opções aqui. Opções é apenas um objeto com chaves diferentes que fornecemos. A chave de consulta e a função de consulta são opções obrigatórias que precisamos passar. A chave de consulta identificará exclusivamente nossa lógica de consulta, nosso fator, como GetStodos, em todo o aplicativo. função de consulta é a lógica para buscar dados. Vamos ver como podemos usar isso. Primeiro, precisamos passar a chave de consulta, e você pode ver agora que é uma matriz. No nosso caso, podemos chamá-lo de algo como show may e, seguida, nosso programa é identificado por ID, conforme você se lembra. Vamos aprovar show e showID. Então precisamos passar pelo buscador. No entanto, você pode ver que agora , no exemplo em que é passada, apenas a função de consulta é getsToDOS. Mas no nosso caso, precisamos de alguma forma obter acesso ao showId dentro do nosso buscador. Nosso buscador é essa função que criamos anteriormente chamada getShowById. Se olharmos a documentação interna, ela está escondida em algum lugar, eu vou te dizer onde. Está aqui na seção Query Keys. Se formos aqui e rolarmos até o final pudermos ver toda essa seção aqui, se sua função de consulta depende da variável incluída em sua chave de consulta. Vamos apenas seguir esses exemplos aqui. Vou apenas copiá-lo e colocá-lo assim. chave de consulta será mostrada em vez de todoID, vamos colocar showId em vez de fetchTodoById, vamos chamar getShowById. Vamos passar o ShowID. UseQuery nos retorna o resultado. Se tentarmos usar o IntelliSense a partir desse objeto de resultado, você verá que temos muitas coisas aqui, mas estamos interessados especificamente nos dados e no somador. Vamos tentar fazer isso. Do objeto resultante, vou pegar os dados e pegar o erro. Vou renomeá-los. Podemos usar dados em vez de showData, mas vamos renomeá-los, vou colocar dois pontos ao lado chave desestruturada e vou chamá-la de ShowData. Dessa forma. A chave de dados que eu desestruturei será renomeada para ShowData. Do objeto resultante, eu ainda desestruturei os dados, mas só queria ter outro nome, ShowData. O mesmo acontece com o erro , será ShowError. Agora, posso realmente voltar ao meu aplicativo e ver como ele funciona. Mas eu preciso iniciar o aplicativo novamente, npm run start, eu volto aqui. Vamos nos refrescar. Você pode ver, bem, nada mudou, no entanto, agora, usamos o gancho useQuery. É uma lógica de gancho personalizada que está escrita em algum lugar dentro da biblioteca tanstack/react-query. Nós apenas o usamos para buscar dados. Você pode ver que esse gancho nos fornece essa interface abstrata para que possamos encapsular essa função em um gancho como useQuery e buscar dados apenas uma vez dentro do componente. Essa chave de consulta aqui é um pouco parecida com aquela matriz de dependências dentro de useEffect. Se algo dentro da chave de consulta mudar, os dados aqui serão obtidos da mesma forma que com useEffect, muito semelhante. Na verdade, a equipe do React nos aconselha a usar algo assim para buscar dados. Na verdade, essa é uma recomendação muito boa. Você não queria lidar com toda essa lógica repetitiva todas as vezes em seu aplicativo. Essas bibliotecas têm muitas opções, são otimizadas para busca, têm essas chaves de cache e podem fazer muito mais do que simplesmente buscar dados em montagens pontuais de componentes. Em aplicativos React modernos, biblioteca de busca de dados é uma ótima opção. Vamos usar useQuery para nosso exemplo específico. Agora podemos remover a lógica que escrevemos anteriormente e, na verdade agora podemos incluir React.StrictMode novamente, porque agora nossa lógica de consulta não será executada duas vezes. Vamos ver isso. Se eu atualizar a página, aqui, tenho apenas uma chamada para a API, o que significa que nossa lógica que escrevemos aqui não será buscada duas vezes e ainda teremos acesso ao React StrictMode. Com essa abordagem, matamos dois coelhos com uma cajadada só. Espero que não tenha sido muito complicado ou sofisticado entender como a busca de dados funciona no React. Começamos com o mínimo com useEffect, porque useEffect pode ser usado para manipular dados e manipular a lógica para o ciclo de vida de um componente Usamos useEffect para buscar dados apenas uma vez quando o componente é montado, mas tivemos que desativar React StrictMode, caso contrário, precisamos escrever alguma lógica para , de alguma forma, superar dupla renderização dentro do modo de desenvolvimento. Para superar isso, usamos uma biblioteca de busca de dados. Em nosso exemplo, instalamos o React Query. React Query nos fornece aquele gancho abstrato useQuery que podemos usar para buscar dados dentro do componente. Espero que faça sentido. Essas bibliotecas de busca são uma ótima opção quando você trabalha com aplicativos React modernos. Vamos confirmar as mudanças que fizemos. O que fizemos foi basicamente instalar o React Query, depois substituímos nosso gancho personalizado fetchShowById pelo gancho useQuery. Também retornamos o React StrictMode para o aplicativo porque não tivemos mais problemas com a busca de dados dentro do useEffect. Agora, vamos adicionar tudo ao estágio, vamos confirmar e, digamos, a consulta de reação instalada, substituída, useShowById pelo gancho useQuery. Incrível. Até a próxima. 74. 18 atribuição: Oi, lá. No último vídeo, falamos sobre bibliotecas de busca de dados. Falamos sobre a consulta React e integramos a consulta React em nosso aplicativo. Usamos o gancho de consulta use dentro do componente show para buscar dados por show ID. No entanto, se voltarmos ao Home jsx, seu componente doméstico, você poderá ver que também buscamos dados aqui. É um pouco diferente de apenas fazer uma solicitação GET simples quando o componente é montado. Como temos basicamente filtros, digitamos algo dentro da caixa de pesquisa , podemos escolher diferentes botões de rádio e clicar no botão Pesquisar somente após o envio da solicitação. No entanto, as bibliotecas de consulta e busca de dados do React também podem lidar com esses cenários. Tenho uma tarefa para você. Você pode integrar o gancho de consulta Use na página inicial para que possamos substituir esses estados de uso aqui por um único gancho de consulta Use. Vá em frente, tente integrar o gancho de consulta Use dentro do componente inicial. Aqui está um conselho que posso lhe dar. Você pode acessar a documentação do React Query especificamente para ver os itens e conceitos que você pode procurar. Deixe-me ver as consultas desativadas e pausadas e, na parte inferior, elas têm esse exemplo com consultas preguiçosas. Você pode usar este exemplo aqui para integrar, use query inside home component. A lógica será muito semelhante a esse exemplo, mas você precisa ajustar essa lógica ao nosso caso de uso. Vá em frente, tente fazer isso e depois compararemos o resultado no próximo vídeo. Te vejo lá. 75. 19 Usando o React Query para pesquisar dados na página inicial: Olá. Como foi sua tarefa? Você conseguiu alcançar o que queríamos? Você conseguiu integrar o gancho useQuery nos componentes domésticos? Vamos tentar ver. Assim como eu disse, você pode consultar esse exemplo para implementar a lógica com o gancho useQuery. O que eu vou fazer simplesmente copiar esses dois aqui e colocá-los em cima. Também precisamos importar e usar Query de react-query. Vamos colocar a entrada no topo. Então, não precisamos usar React.useState porque importamos useState diretamente da biblioteca e agora precisamos ajustar isso ao nosso caso de uso. Em primeiro lugar, o que é essa chave habilitada aqui? O fato é que há situações em que queremos buscar dados condicionalmente, porque essa lógica, por padrão, é executada quando o componente é montado. Os dados são obtidos quando o componente é montado. No entanto, isso nem sempre é verdade. E se tivermos uma opção, e quando essa alternância for verdadeira, ou quando aplicarmos o filtro somente então quisermos buscar a lógica. Nesse caso, podemos usar a opção habilitada aqui para permitir react-query entenda que queremos executar ou não essa lógica. No nosso caso, temos filtros. Nossos filtros são a sequência de caracteres de consulta, tudo o que digitamos dentro da caixa de pesquisa. Depois, também temos a opção de pesquisa, que é o valor para ler seu botão que selecionamos, sejam programas ou atores. Esses são os filtros que temos. Como gerenciamos toda a lógica relacionada à inserção desses filtros para selecionar e ler seus botões, gerenciamos tudo isso dentro do SearchForm. Em seguida, passamos os dados de volta para casa usando a função OnSearch aqui. Precisamos pensar de alguma forma em como podemos passar essas informações do filtro para o gancho useQuery. Podemos usar, digamos, estados auxiliares para filtros e, em seguida, podemos passar esse filtro como parte da QueryKey. Se o filtro for nulo ou estiver vazio, não selecionamos nada, simplesmente desativamos a consulta, porque quando entramos na página, não queremos buscar dados porque, bem, não temos filtros. Não inserimos nada. No nosso caso, filtre por padrão, em vez de uma string vazia, ela será nula e a passamos para a opção habilitada. Somente se o filtro for verdadeiro, poderemos consultar os dados. Nesse caso, o gancho será ativado. Em seguida, também passamos o filtro como parte da QueryKey. Isso significa que se o filtro mudar, se esse valor mudar de alguma forma, no nosso caso, será um objeto. Se esse objeto for alterado, ReactQuery entenderá isso e a QueryKey mudará, e o gancho UseQuery revalidará a consulta. Ele executará novamente a consulta com a nova QueryKey. Basicamente, o QueryFunction que fornecemos aqui será executado. Novamente, ele atualizará os dados e preencherá novamente a variável de dados que temos aqui. Chega de falar, vamos finalmente fazer alguma coisa. Em primeiro lugar, precisamos definir esse filtro aqui. Faremos isso dentro da função Onsearch que temos aqui. Não precisamos de todos esses blocos para tentar pegar. Eu só vou comentar isso. Dentro do Onsearch, vou apenas chamar setFilter e definir setFilter para qualquer string de consulta que tenhamos e qualquer SearchOption que tenhamos. Então, como eu disse, passamos o filtro como parte da QueryKey em vez de todos. Vamos chamá-lo de algo como pesquisa, isso realmente não importa. Dentro de QueryFunction, precisamos de alguma forma colocar lógica que temos aqui com base na SearchOption. Dentro dessa QueryFunction, perguntaremos se filter.searchOption é isso que definimos e, quando eu escrever a lógica dentro desse filtro QueryFunction, ela não será nula. Porque, como você se lembra, a consulta será desativada quando o filtro for nulo em nosso caso. Isso significa que é seguro escrever aqui filter.searchOption sem se preocupar com o fato de o filtro ser potencialmente nulo e isso nos gerará um erro. Algo como não é possível ler as propriedades searchOption de null. Se o filtro SearchOption = mostrar, nesse caso, pesquise ForShowsFilter.q, caso contrário, SearchForPeopleFilter.q. É isso mesmo. Agora podemos remover a lógica que tínhamos anteriormente na pesquisa. Podemos remover esses dois ganchos useState aqui, dados que desestruturamos do gancho useQuery, vamos chamá-los de ApiData, um erro que desestruturamos, vamos chamá-lo de ApiDataError. É isso. Eu removo esse comentário indesejado e vamos ver o que temos. Vamos inspecionar o console. Vamos inspecionar a guia Rede. Vou digitar algo como olá. Clique em “Pesquisar” e você verá que funcionou. Bem, o mesmo comportamento que tínhamos anteriormente. Se eu mudar para atores e digitar garotos. Por exemplo, aqui temos a solicitação, se eu voltar para shows e depois fizer novamente, algo como meninas, você verá que os dados são buscados. Porque, novamente, o filtro muda sempre que pressionamos o botão Pesquisar. Sempre que clicamos no botão Pesquisar, atualizamos o estado do filtro. estado dos filtros é atualizado, QueryKey fica, digamos, invalidado, ele muda. Isso significa que o ReactQuery buscará novamente os dados com o filtro mais recente, com a última QueryKey que passarmos. Simples assim. Você provavelmente já percebeu esse comportamento estranho, quando você pode ver várias solicitações sendo processadas. O fato é que o ReactQuery tem algo chamado busca novamente de dados ao refocar. Esse é um dos recursos dessas bibliotecas de busca de dados. Sempre que você tentar reorientar a janela, ela atualizará os dados. Você pode ver se eu clico dentro do trabalho de rede e, em seguida, clico em algum lugar dentro da página novamente, ela sempre envia a solicitação. Esse comportamento, na maioria das vezes, pode ser desejado, mas no nosso caso, esse comportamento é definitivamente indesejado. Podemos desativar isso. Dentro das opções, vou passar RefetchOnWindowFocus e, se você passar o mouse, poderá ler a descrição do que exatamente essa opção faz, o que a manterá como falsa. Vamos ver. Vamos procurar alguma coisa. Se eu tentar reorientar a janela novamente, nada acontecerá. Algo parecido. Agora, temos o useQuery também dentro do componente inicial, parabéns. Eu realmente espero que você tenha acertado essa tarefa. Pode ser muito desafiador, e definitivamente foi porque é algo novo, uma nova biblioteca, uma nova lógica. Mas você pode ver que, quando se acostuma, não há nada realmente complexo no final. Vamos confirmar as mudanças que fizemos. Vai ser bem simples. Vamos apenas dizer que edite ou use o Query na página inicial para buscar dados de pesquisa. Incrível. Enviando tudo para o GitHub e até o próximo. 76. 20 Mostrando informações na página Mostrar: Olá, novamente, no último vídeo adicionamos o gancho de consulta de uso à página inicial e agora temos o ciclo completo de busca de dados em nossos componentes. Mas, como criamos a página de exibição, precisamos exibir os dados de exibição nessa página. Isso é exatamente o que vamos fazer neste vídeo, vamos preencher os dados na página do programa dentro do componente show, vamos lá. Quais dados precisamos exibir? Se dermos uma olhada na resposta da API, é isso que recebemos em nossos dados. Precisamos decidir o que exatamente queremos exibir na página , então vamos criar alguns componentes e eu já tenho uma ideia, então vamos em frente. Em primeiro lugar, na pasta show, vou criar um novo arquivo chamado ShowMainData.jsx. Isso vai ser um componente. Mas agora ele retornará um simples padrão de exportação div para mostrar os dados principais. Em seguida, também criarei, deixe-me ver outro componente que chamarei de detalhes, detalhes do jsx e provavelmente adicionaremos outra coisa. Por enquanto, isso é suficiente , voltamos à página de exibição. Aqui temos esses dados do show, showData.name. Em vez disso, vamos usar o componente show main data que importamos dos componentes, mostra showMainData onde agora o mantemos assim. Depois disso, vamos exibir os detalhes. Aqui, podemos ver os detalhes na tag h2 e , em seguida, exibir os detalhes Também precisamos importá-los de shows details. Tudo bem, deixe-me salvá-lo, deixe-me voltar para a página do programa e aqui tenho olá, olá, exatamente o que temos dentro de nossos componentes por enquanto. O que vamos exibir dentro do ShowMainData? Acho que precisaremos do nome do programa, algo como grade, resumo e imposto, deixe-me ver. Temos um nome aqui, temos gêneros, temos média ou não média, média de classificação, então vamos exibir tudo isso dentro de ShowMainData, vamos passar para lá. Antes de tudo, também precisamos de uma imagem e, se você se lembrar temos essa mídia original e ela pode ser nula. vamos lidar com casos nulos dentro Desta vez, vamos lidar com casos nulos dentro do componente , então vamos passar showData.image e depois passaremos o nome que será showData.name e depois passaremos a classificação. A classificação será apenas deixe-me encontrá-la, apenas a média de classificação, passaremos o objeto e manipularemos. Média dentro do componente, classificação ShowData, então precisaremos de um resumo, pois lembramos que exibimos versão muito curta do resumo dentro cartão de exibição. Desta vez, exibiremos o resumo completo na página de exibição. Vamos passar um resumo que está localizado aqui. Esta é a string HTML, conforme você se lembra resumo de ShowData e, em seguida, passaremos os gêneros. Deixe-me encontrar gêneros aqui. Esta é apenas uma variedade de gêneros deste programa, gêneros ShowData. Incrível. Agora vamos entrar ShowMainData e pegar todas essas instruções. Vamos pegar imagens, vamos pegar nome, classificação, resumo e gêneros. Agora, o que vamos escrever dentro dessa div, antes de tudo, precisaremos exibir a imagem. A fonte será Image.medium, como você se lembra, mas desta vez vamos exibir a imagem original em vez da pré-visualização em tamanho médio. No entanto, precisamos lidar com os casos de uso nulos conforme você se lembra , então vamos perguntar se a imagem é verdadeira, as imagens estão definidas? Em seguida, use a imagem original, caso contrário, use a imagem não encontrada. Se eu voltar para o cartão de exibição ou para a grade de exibição, tenho uma lógica bem semelhante aqui, vou apenas reutilizar a imagem não encontrada em png e colocá-la aqui e, se você lembrar que imagem não encontrada em png e colocá-la ela colocada dentro da pasta pública, ela será exibida sob a raiz. Ao lado da imagem, talvez também vamos adicionar alt aqui, que será mostrado nome, então exibiremos as informações, então vamos separar esse bloco com um div. Aqui, vamos colocar algo como nome como título e, em seguida, exibiremos aqui a classificação para que possamos colocar classificação como média, esse objeto, mas a classificação também pode ser nula ou, se eu não estiver errado, a média da classificação pode ser nula ou não definida ou pode ser zero. Não tenho certeza disso, mas a média de classificação dessa estrutura sempre será a mesma. Nesse caso, podemos fazer algo se a média da classificação for algo verdadeiro ou digamos que não seja zero, podemos usar o operador or. O que quero dizer é que suponha que tenhamos uma classificação média zero. Vamos criar essa média aqui, é zero, então vamos exibir a média ou olá e você pode ver olá sendo impresso , o que significa que a média não foi aprovada porque é falsa e zero é considerado um valor falso. Nesse caso, exiba olá. Vamos aplicar exatamente a mesma lógica aqui, então, se a média for zero ou se for falsa nesse caso, exiba N/A, faz sentido? Em seguida, vamos exibir o resumo, mas aqui está o problema. Vamos tentar fazer isso, vamos ver o que teremos. Vamos voltar ao nosso aplicativo e temos uma imagem bem grande aqui. Tudo bem, vamos aumentar e rolar para baixo. Aqui você pode ver que obtemos a string HTML como está. Na verdade, a string HTML a considera como uma string, não como HTML. Se olharmos dentro dos dados , é apenas uma string e o React não sabe que isso é HTML. Para tratarmos o HTML como se fosse HTML, precisamos usar o seguinte. Antes de tudo, vamos transformar esse div em um componente de fechamento automático e, para esse div, podemos passar algo chamado DangerouslySet innerHTML. Este é um suporte especial do React, deve ser um objeto e esse objeto tem propriedade HTML e passamos um resumo para dentro. Com essa construção, React entende que queremos tratar o HTML na verdade como HTML. Vamos tentar ver. Agora você pode ver que não temos nenhuma tag HTML aqui e, se inspecionarmos a marcação, qualquer HTML que recebemos será realmente tratado como HTML. Por que isso é definido como DangerouslySetInnerHTML? O problema é que quando você deseja, digamos, exibir HTML ou injetar HTML na página, ela pode conter JavaScript malicioso. Portanto, para evitar isso, React avisa que, se você quiser ter certeza de que deseja inserir HTML na página, a decisão é totalmente sua e a precaução é que você precisa usar dangerouslySetInnerHTML porque é perigoso. Ao lado do resumo, vamos mostrar os gêneros. Podemos dizer os gêneros e por que eu tenho um ponto de interrogação aqui. Os gêneros serão, deixe-me ver, então temos que é uma matriz, o que significa que podemos mapear cada elemento para a marcação jsx. Vamos usar o método.map, vamos lá. Vamos criar outra div aqui e os gêneros serão gêneros. mapa. Aqui teremos gênero e talvez exibiremos uma tag span e, por dentro, podemos exibir o gênero. Quando usarmos o.map para mapear a marcação jsx, precisamos passar a chave exclusiva para o elemento do mapa. Deixe-me ver que os gêneros são bastante únicos, eu diria, então podemos passar o gênero em si como a chave única. Vamos tentar ver. Eu amplio, temos gêneros, comédia, família. Eu acho que esse programa tem apenas um gênero. Tem comédia e família. Como não temos espaço, parece que essa é uma única string, mas não é. Não preste atenção, pois, por enquanto, isso não tem estilo. Por enquanto, lidamos apenas com a lógica dentro de nosso aplicativo. final, lidaremos com o estilo. Agora deixe-me ver, então usamos todos os problemas que queríamos. Por enquanto, acho que é isso. Vamos mais longe e lidar com os detalhes. Quais detalhes internos vamos mostrar? Deixe-me ver que tipo de dados temos aqui? Provavelmente exibiremos algo como o status do programa, se ele ainda está em exibição, ele terminou ou talvez tenha acabado de ser lançado e quando exatamente esse programa estreou, e talvez a rede, onde exatamente o programa foi publicado. Em qual região, em qual canal de TV, algo assim. Para detalhar o componente, vou passar primeiro o status e isso será apenas showData.status, então provavelmente quando o programa estreou, então será apenas ShowData.premiered e depois network. A rede é apenas um objeto, ShowData.network. Legal. Eu o guardo. Desta vez, vou para o componente Details aqui, passo status premiered network e vou pegar status premiered network ou talvez vamos usar outra sintaxe desta vez apenas para fazer novamente, digamos, uso casual do JavaScript. Em vez de desestruturar adereços diretamente dentro dos argumentos da função, faremos isso em uma linha separada só porque queremos que seja assim, nada de especial nisso. Aqui, em vez de “olá”, vou apenas dizer, talvez adicione uma tag de parágrafo e diga “status é status”. Então, dentro de outro parágrafo, direi “estreou nesta data” e depois exibiremos a rede. No entanto, essa rede também pode ser nula porque nem todos os programas contêm essas informações, então precisamos lidar com esse caso. Precisamos presumir que, na verdade, essa é uma boa prática quando você trabalha com algo desconhecido É muito bom supor que algo pode ser nulo ou indefinido ou pode nem mesmo ser passado. Vamos perguntar à rede, se ela é confiável, se existe? Nesse caso, exibiremos uma sequência de caracteres, algo como estreada nesta data em um canal ou país específico. Provavelmente vamos escolher apenas o nome, estreou nesta data em network.name. Usei crases para especificar que queremos usar a interpolação de string dentro da string e, em seguida, interpolo o nome da rede dentro da string do nome da rede. Caso contrário, exiba nulo, não exiba nada ou podemos ter certeza de que usamos o valor booleano aqui. Podemos transformar a rede em um valor booleano e em vez de usar o operador ternário, podemos usar a extremidade lógica. Nesse caso, nenhum nome de rede será exibido somente quando a rede for verdadeira. Agora, vamos ver o que temos e temos o status encerrado e estreado nesta data na CBC. Incrível. Agora, parece que exibimos quase tudo o que queríamos. No entanto, podemos dar mais um passo e exibir mais dados, como informações sobre temporadas e informações sobre o elenco. O que precisamos nesse caso? Se analisarmos os dados da API que recebemos, não temos nenhuma informação sobre elencos ou shows. Mas se voltarmos à API do TV Maze, aqui temos esta seção, deixe-me ver, sobre incorporação. incorporação nos permite carregar mais dados sobre o programa, e aqui está um exemplo. Deixe-me abri-lo. O URL tem essa aparência. Incorporamos episódios, incorporamos elenco e, se rolarmos para baixo, veremos esta seção embutida de sublinhados com episódios e elenco. Isso é exatamente o que vamos fazer, mas precisamos modificar nossa função para pesquisar e mostrar. Vamos copiar essa parte incorporada e usar a função getShowById para obter dados. Aqui no URL, podemos adicionar incorporação, episódios e elenco. Mas em vez de episódios, vamos incorporar temporadas. Também podemos obter informações sobre as temporadas. Em vez de episódios, vamos especificar temporadas. Nós o salvamos, voltamos ao programa e agora ele foi revalidado porque você lembra que, e agora ele foi revalidado porque você lembra que ao alternar o foco entre a janela e outra coisa, os dados serão atualizados porque usamos o gancho useQuery e podemos evitar seu comportamento usando RefetchOnWindowFocus. Se você não quiser esse comportamento, na verdade, provavelmente não precisamos desse comportamento, vou desativá-lo da mesma forma que fizemos na página inicial. Vamos ver o que temos nesse caso. Você pode ver que agora temos esta seção embutida de sublinhados, aqui temos informações sobre o elenco e as temporadas. Na verdade, vamos copiar esse URL, abri-lo aqui e inspecionar a forma dos dados das temporadas e do elenco. Antes de tudo, precisamos criar componentes correspondentes para as temporadas e o elenco. Na pasta Shows, vou criar cast.jsx e vou criar seasons.jsx. Vou copiar rapidamente a marcação, então, por enquanto, será div, adereços, vamos desestruturá-los em linha e vou chamá-la de Cast. O mesmo que farei com as temporadas. Agora vamos usar esses componentes dentro da mostra aqui. Então, na próxima div, teremos algo como div novamente, outra tag de título que dirá Seasons. Aqui vamos exibir o componente Seasons. Foi importado automaticamente. Se eu olhar para o topo, ele foi importado das temporadas de shows de componentes. Vou copiar isso. Em vez de temporadas, agora vou exibir o elenco e depois importar o elenco novamente. Como importar? Eu pressiono “Tab”, boom, importado na parte superior. Ótimo. Quais dados eu vou passar? Para o componente Seasons, vou passar o adereço Seasons, e Seasons será sublinhado nas temporadas incorporadas. Isso é o que recebemos da API, então vou passar a mostrar dados sublinhados incorporados. Certifique-se de não escrever incorretamente, .seasons, e exatamente o mesmo que farei com o elenco, mas em vez de passar as temporadas, passarei o adereço do elenco, ShowData embedded.cast. Agora, dentro de Seasons, vou desestruturar o suporte de temporada que passamos. Vamos ver o que vou mostrar aqui. Em primeiro lugar, queremos saber quantas temporadas temos no total. Se eu voltar ao aplicativo, terei esse problema: padrão inesperado de objeto vazio. Vamos corrigir isso rapidamente. Se formos para o Cast, vou simplesmente remover isso. Então, dentro de Seasons, o que vou mostrar. Em primeiro lugar, dentro da tag p, vou exibir as temporadas no total. Vamos verificar se temos isso, temporadas no total. Aqui vamos adicionar seasons.length. Se analisarmos nossos dados, as temporadas são apenas uma matriz. Portanto, cada temporada é um item da matriz, o que significa que o número de elementos é igual ao número de temporadas. Bem, parece que é lógico, então vamos usar seasons.length. Ao lado das temporadas no total exibiremos episódios no total e diremos, deixe-me ver. Como temos as temporadas como uma matriz e dentro de cada elemento, temos a ordem dos episódios e, basicamente, quantos episódios temos em uma única temporada? Precisamos calcular de alguma forma o número total de episódios em toda a lista de temporadas. Podemos usar algo array.reduce para calcular isso. Então, vamos contar seasons.reduce. A redução de temporadas será por padrão agora, então vamos reduzir toda a nossa matriz de temporadas em um número. Comprimiremos essa matriz de temporadas em um número. Basicamente, analisaremos cada elemento da matriz e resumiremos a ordem dos episódios. Aqui esta será nossa soma e o segundo elemento aqui será o elemento atual da matriz que será repetido. Esta vai ser a temporada. Então, vamos dizer, por favor, devolva-nos um pedido adicional de temporada/episódio. Vamos tentar ver se não temos nenhum pedido. Temos temporadas no total uma, episódios no total 13. Ótimo, funcionou. Agora, ao lado do parágrafo, exibiremos os dados de cada temporada, basicamente, essas informações, o que significa que precisamos mapear cada elemento da temporada com a marcação jsx. Vamos usar o método do mapa de pontos. Vamos dizer seasons.map, season. Vamos mapeá-lo para um div ou agora diga olá ou chave, vamos passar a temporada. deixe-me ver os dados. A temporada tem um ID que é representado de forma exclusiva para que possamos usá-lo com segurança como chave. Vamos dizer, por favor, exiba temporada, temporada.número, então o número da temporada. Ótimo. Em seguida, vamos exibir a tag p. Vamos contar aos episódios quantos episódios esta temporada tem. Provavelmente, na ordem dos episódios da temporada, podemos usá-la, por que não? Em seguida, mostraremos quando esta temporada foi ao ar, e podemos usar a data de estreia e a data de término. Ótimo. Então, deixe-me separá-lo em um div separado, então eu direi ao aired. O que vou fazer dizer Season.PremiereDate, SeasonEndDate. Provavelmente isso, sim. Vamos tentar ver. Temos temporadas no total, episódios no total, então temos a primeira temporada que tem 13 episódios e foi ao ar desta data até esta data. Parece bom para mim. Se precisarmos adicionar algo mais, faremos isso mais tarde, por enquanto isso bastará. Vamos trabalhar no componente do elenco desta vez. Para o componente fundido , passamos o suporte fundido. Então, aqui dentro do componente fundido , vou pegar o suporte fundido e vamos pensar em quais dados vamos exibir aqui. Vamos inspecionar a API. O elenco também é apenas uma matriz e cada matriz tem essa pessoa, personagem, eu e voz Keith. Vamos ver o que vamos fazer. Provavelmente vamos mapear cada elemento da matriz para algumas informações e exibi-las aqui. Vamos fazer isso. Então, vamos simplesmente fazer cast.map. Vamos chamá-lo de item e vamos mapeá-lo para um div por enquanto. A chave será, deixe-me ver, item person.id, provavelmente isso. Eu acho que isso será bem único. Dentro da div, primeiro lugar, vamos exibir, deixe-me ver, provavelmente uma imagem real. Vamos tentar fazer isso. Vamos colocar essa imagem em um div por enquanto. A imagem será item.person.image, mas você lembra que a imagem pode ser nula, então precisamos lidar com isso. Se item.person.image existir, nesse caso, use item.person.image.medium. Caso contrário, use novamente, vamos pegar, vamos usar a imagem não encontrada png. Ótimo, vamos salvá-lo. Então, ao lado da imagem que vamos exibir, deixe-me ver, temos item.person.name e depois vamos exibir o personagem dentro desse programa nesse programa. O personagem será o nome do personagem, então essa pessoa jogou item.character.name. E você sabe o que? É muito repetitivo digitar item ponto alguma coisa toda vez, então, a partir desse item vamos desestruturar a pessoa e o personagem. Em vez de escrever item dot toda vez, vamos escrever person.character. Então character.name. Deixe-me ver como podemos usar outra coisa. Nós temos esse eu e essa voz aqui. A voz provavelmente se refere a se essa foi apenas a narração e se o papel não foi desempenhado diretamente no programa. Foi apenas uma narração dessa pessoa, então talvez possamos usá-la. Também podemos desestruturar a voz a partir daqui porque é a chave do nosso item e vamos perguntar se essa pessoa cuida da narração. Vamos apenas exibir algo como outro tubo porque isso é o que usamos aqui e vamos dizer voice over, caso contrário, uma string vazia ou podemos usar novamente o operador and e queremos ter certeza de que isso será um booleano, mas acho que esse valor aqui sempre será um booleano, então não precisamos transformar essa variável, esse valor em um valor booleano aplicando dupla negação ou usando o construtor booleano. Isso será suficiente, eu acho. Agora vamos tentar ver nosso resultado final. Temos a seguinte página de apresentação. Deixe-me torná-lo menor. No momento, sei que não tem estilo, mas vamos cuidar disso, não se preocupe. Temos tudo o que queremos sobre o programa. Incorporamos o resumo, exibimos a classificação média do programa, exibimos gêneros, exibimos detalhes quando foi ao ar, talvez quando foi encerrado, exibimos informações sobre as temporadas e exibimos informações sobre o elenco. Qual foi a pessoa que interpretou esse papel e essa pessoa era um personagem de dublagem ou era qualquer personagem da série. Acho que é isso. Na verdade, foi muito. Trabalhamos com dados de API, criamos componentes correspondentes para exibir dados. Onde agora vamos comprometer tudo. Vamos dar uma visão geral rápida do que temos aqui. Modificamos a função get show by id para buscar dados, incorporamos temporadas, incorporamos elenco e usamos as informações que obtemos da API e exibimos essas informações na página do programa. Criamos componentes correspondentes, passamos os adereços correspondentes e depois manipulamos tudo dentro de cada componente correspondente, algo assim. Vou adicionar tudo ao palco e minha mensagem de confirmação exibirá dados detalhados do show na página do programa. Legal. Mais uma coisa que eu gostaria de salientar aqui é que, como você se lembra, desabilitamos esse comportamento RefetchOnWindowFocus da consulta use who. Agora, quando revalidarmos, desculpe-me, deixe-me iniciar o aplicativo novamente. Onde está nossa página do programa? Opa, eu o fechei acidentalmente. O que quero dizer é que, quando reorientamos a janela agora, os dados não são atualizados o tempo todo , mas o que acontece se nosso ID de show não existir? Vamos tentar ver. Vamos tentar algo sem sentido. Vamos ver o que temos? Vemos que os dados estão sendo carregados e podemos ver esse comportamento de repetição. Na verdade, você pode ver que a solicitação foi enviada três vezes e, se, no momento em que a terceira solicitação for atingida, ainda tivermos um erro nossa solicitação, então use query exibirá um erro. Você pode ver que a biblioteca de busca de dados é algo mais do que simples Busque meus dados quando o componente for montado. Essa busca de dados pressupõe que as solicitações podem falhar e, se falhar, a repetirá automaticamente algumas vezes com algo chamado recuo exponencial. Por exemplo, se nossa solicitação falhar pela primeira vez, a solicitação será repetida após um segundo; se falhar, a próxima tentativa ocorrerá após dois segundos e próxima tentativa ocorrerá após três segundos. Use query cuida disso. Muito legal. É isso. Nos vemos na próxima. 77. 21 Adicionando o botão voltar na página Mostrar: Olá de novo. No último vídeo, criamos componentes nos quais exibimos dados sobre um programa específico na página do programa. Foi bem longo. Agora precisamos pensar um pouco mais sobre a experiência do usuário. O que quero dizer com isso? Suponha que estejamos na página inicial, procuraremos um programa específico clicaremos em Leia mais. Acabamos na página do programa. Agora, não temos nenhum botão extra para navegação aqui, o que significa que o usuário precisa clicar em Voltar para a página anterior e, se voltarmos para essa página, veremos que todos os nossos dados sumiram, precisamos iniciar a pesquisa novamente. O que podemos fazer nessa situação. Antes de tudo, precisamos adicionar na página do programa um botão que levará o usuário de volta à página inicial. Isso será um pouco mais conveniente para o usuário. Mesmo assim, isso não resolve o problema de os dados quando o usuário retorna a essa página e bilheteria Nós não lidamos com isso, mas, idealmente, precisamos lembrar de alguma forma a última pesquisa que fizemos para que, quando o usuário volte para aquela página, ela ainda está lá. Não vamos abordar isso na bilheteria, vamos apresentar uma alternativa. E se procurarmos o programa e, quando clicarmos em Leia mais, ele levará o usuário para a nova guia? Ele abre esta página de exibição na nova guia. Vamos seguir em frente e fazer isso. Se voltarmos ao componente show card que temos, usamos esse componente de link aqui. Usamos o componente de link porque usamos biblioteca de roteamento do lado do cliente react-router e, para que possamos lidar com a navegação adequadamente por meio de links, usamos esse componente de link especial importado do roteador React dom. Mas se quisermos abrir algo em uma nova guia, isso não está relacionado ao roteamento do site do cliente. Nesse caso, podemos usar uma tag âncora simples em vez de usar o componente de link do roteador React dom. Então, podemos simplesmente removê-lo e, em vez de usar o clink, exibiremos a tag âncora. etiqueta de ancoragem tem uma propriedade de calha. Agora podemos fornecer outro atributo da tag âncora chamado target e especificamos o sublinhado em branco. Assim que eu especifico em branco como o destino, recebo este erro do link ES vindo do React JS x target blank, que, por favor, use a relação não referenciada. Eu só vou copiar não especificado. Essa é apenas uma medida de segurança muito pequena. Eu o guardo. Agora, vamos tentar. Se eu clicar em Leia mais, ele abre minha página de exibição em uma nova guia. Muito legal. No entanto, novamente, como concordamos em tornar a experiência do usuário um pouco mais conveniente, adicionaremos o botão Voltar ao Início em algum lugar na parte superior. Vamos para o componente da página de exibição. Aqui na parte superior, logo acima de mostrar os dados principais. Podemos acrescentar duas coisas aqui. Podemos adicionar um componente de link que nos leve de volta para casa, algo assim, voltar para casa, e essa é uma solução totalmente boa. Na verdade, vamos usar esse. Mas eu só quero que você veja a alternativa para isso. Porque o roteador React é uma biblioteca de roteamento. Tem algo a oferecer. Vamos dar uma olhada nisso. Mesmo assim, podemos usar o componente de link. Em vez de usar o clink por enquanto, adicionaremos um botão e diremos : “Volte para casa”. Nesse botão do tipo botão, vamos ativar o manipulador de clique, Voltar e esse, ao voltar, faremos algo por nós. Se voltarmos à documentação do react-router, ela terá algo chamado use navigate. Usar o gancho de navegação, olhando este exemplo, nos permite navegar programaticamente entre as páginas, ainda usando o roteador React dom. Em vez de usar o componente de link, digamos que de forma mais declarativa, usamos a função que fará a navegação basicamente programaticamente e de forma mais imperativa. Olhando esse exemplo, posso pegar e usar a navegação a partir do roteador React dom. Na verdade, eu já importei, então vou fazer assim. Desculpe-me, não use parâmetros, use navegar. Então vou ligar para usar navegue aqui. Esse uso de navegação nos retorna uma função que precisamos chamar para navegar até uma página específica. Navegue até, vou chamá-lo assim. Quando clicamos em, voltamos para a página inicial, ligamos para navegar até e, em seguida, especificamos, voltamos para a página inicial. Vamos voltar ao aplicativo. Além disso, temos esse botão aqui. Novamente, esse botão não vincula o componente, é um botão. Se clicarmos, voltaremos para casa. Caso você precise navegar programaticamente ou redirecionar o usuário para uma página, você pode usar o gancho de navegação de uso. Mas, no nosso caso, não precisamos realmente transformar o botão em um link programaticamente. Podemos usar diretamente o componente de link porque ele realmente faz mais sentido. É por isso que não vamos usar, usar a navegação, que ficará com o componente de link. simples quanto isso. Agora, vamos tentar ver. Se olharmos para dentro da marcação. Agora, na verdade, é a etiqueta âncora. Legal. Se clicarmos nele, ainda voltaremos para casa. Mas isso exige que usemos menos código. Na verdade, é melhor porque agora faz a marcação adequada, a marcação HTML adequada para navegar entre as páginas, pois é uma tag âncora. Legal. Agora, aumentamos um pouco a experiência do usuário. Agora parece muito, muito melhor. É isso por enquanto. Vamos confirmar as mudanças. Adicionamos voltar à página inicial e abrimos a página de exibição em uma nova guia. Vou contar dentro da minha mensagem de confirmação botão Abrir ou Ler mais leva o usuário a uma nova guia agora, adicionado o link Voltar à página inicial na página de exibição. É isso. Empurre tudo para se levantar. Eu vou te ver na próxima. 78. 22 Introdução ao useReducer como alternativa ao useState: Ei, no último vídeo, falamos um pouco sobre a experiência do usuário. Agora, quando clicamos em Leia mais, ele abre a página de exibição dentro de uma nova guia, assim como adicionamos o botão “Voltar para a página inicial” . Tudo isso é ótimo. No entanto, não temos a funcionalidade do botão “Star Me”. Sempre que clicamos nesse botão, queremos marcar o show como estrela. Posteriormente, quando navegarmos até a página com favoritos, podemos ver nossa lista de favoritos aqui. Como podemos conseguir isso. Antes de podermos fazer isso, precisamos analisar a alternativa de usar o estado. Vamos voltar ao nosso componente. Digamos que, provavelmente, para a página inicial. Aqui vamos jogar com o novo gancho. Como você já sabe, se quisermos ter algum valor que mude ao longo do ciclo de vida do componente, precisamos usar o gancho useState. Basicamente, é apenas um valor que muda. Ele nos fornece a variável de estado e a função que podemos usar para atualizar esse estado. Essa é a nossa maneira de gerenciar o estado local de um componente. Existe uma alternativa para usar o estado chamada UseReducer. É uma alternativa, significa que não substitui useState, assim como useState não substitui useReducer. Você pode usar o que quiser e o que achar mais apropriado. Se tivermos useState e tivermos, digamos, definir a função de filtro que podemos chamar para liderar o estado com useReducer, temos algo chamado ações. Na verdade, iniciamos uma ação e, em seguida essa ação é tratada por uma função, e essa função decide como atualizar o estado com base em uma ação. Vamos dar uma olhada no exemplo de um contador. O gancho do qual eu estava falando é UseReducer. Vamos definir o que é um redutor em um segundo. Aqui em cima, vou chamar UseReducer. Esse useReducer como primeiro argumento recebe algo chamado redutor. Além disso, vou criar a função redutora. Agora será uma função vazia e eu a passarei para useReducer. Como segundo argumento, preciso passar pelo estado inicial. Assim como no caso de useState, nosso estado por padrão será zero porque vamos implementar counter. Quando clicamos em um botão, queremos incrementar ou diminuir. UseReducer, assim como useState, nos retorna uma matriz de exatamente dois elementos. Vamos desestruturar esses dois elementos. O primeiro elemento, novamente , será o estado, assim como com o useState. Digamos que contador. O segundo elemento será algo chamado despacho. Agora, o que eu preciso fazer para atualizar o estado de alguma forma? O conceito de redutor, portanto, esse gancho UseReducer é baseado no conceito de redutores. Deixe-me abrir a pintura e explicar uma coisa. Basta visualizar a ideia do UseReducer. Com o UseReducer, abordamos ações que são tratadas por uma única função chamada redutor. Temos várias ações acontecendo em nosso estado. Por exemplo, no caso de contador, temos incremento. Deixe-me torná-lo um pouco maior e então teremos um decréscimo. Digamos que temos outra ação chamada algo como reset counter, reset. Então, todas essas ações são enviadas por essa função de despacho para a lógica interna do React. Então, temos uma única função chamada redutor, que manipula todas essas ações recebidas. Sempre que uma ação está sendo despachada, ela está sendo tratada pela função redutora e qualquer coisa que a função redutora retorne será o novo estado. Todo esse fluxo substitui o gancho useState e é baseado no conceito de redutor. Agora, o que é o redutor? Assim como mencionei anteriormente, redutor é apenas uma função que, de alguma forma, manipula essas ações. Mas quais são essas ações? Esse é o ponto. Precisamos definir ações nós mesmos. Uma ação, nesse caso, é apenas um objeto que transmite alguns dados. Por exemplo, podemos definir uma ação para incrementar dados. Normalmente, quando falamos de redutores, quando falamos sobre todo esse conceito, uma ação sempre será um objeto. Com o tipo, digamos, incremento e alguma carga adicional. Pode ser qualquer coisa. Pode ser um novo valor, seja o que for. Esse objeto pode assumir qualquer forma. Mas geralmente ele tem esse tipo, chave e carga útil apenas para torná-lo mais consistente. Precisamos definir essas ações nós mesmos. Em seguida, eles são manuseados dentro do redutor. Eu vou para cá. Dentro da marcação JSX, vou dizer que o contador será um contra-ataque, interpelará o estado. Em seguida, adicionarei dois botões aqui. Um será incremento, o segundo será decréscimo e o terceiro será redefinido. Cada função terá esse onClick e vamos nomear esses manipuladores como onIncrement, depois onDecrement e onReset. Agora precisamos criar essas funções. Vamos fazer isso aqui em cima. Temos onIncrement, depois temos onDecrement e temos onReset. Algo precisa acontecer. Precisamos enviar ações para , de alguma forma, atualizar o estado. Podemos ligar para o despacho. Aqui precisamos aprovar uma ação. Por exemplo, quando ocorrem incrementos, enviamos uma ação. Novamente, uma ação é apenas um objeto. Vamos pegar esse, na verdade. Não precisamos de nenhuma carga útil aqui por enquanto. Vamos apenas enviar uma ação e ela será um objeto do tipo INCREMENT. Quando diminuímos, queremos enviar uma ação DECREMENTO. Se tivermos uma reinicialização, podemos enviar uma ação do tipo RESET. Novamente, esses são os objetos que nós mesmos definimos para nós. Será mais fácil para nós entendê-los. Sempre que esse despacho estiver sendo chamado essa ação será tratada pela função redutora. Essa função redutora deve retornar um novo estado. Por enquanto, vamos retornar zero. Essa função redutora recebe dois argumentos. Em primeiro lugar, ele recebe currentState. Assim como no caso da função de atualização de estado com useState quando passamos o retorno de chamada. Temos acesso ao currentState como primeiro argumento. A mesma ideia está aqui dentro do redutor. Temos currentState, vamos chamá-lo de CurrentCounter. segundo argumento é a ação que enviamos. Vou registrar currentCunter e action. Vamos voltar aqui. Nós temos algo assim. Vamos inspecionar o console. Sempre que clico em Incrementar, vejo duas coisas sendo consoladas. Vejo que currentCounter é igual a zero. Esse é o nosso estado atual. Nós temos ação. Ação é exatamente o que passamos quando chamamos a função de despacho, essa será essa ação aqui. Com base no que passamos, com base no que despachamos, podemos escrever nossa lógica dentro de uma única função. Normalmente, quando você trabalha com redutores, trabalha com o estojo do interruptor. Vamos mudar action.type. Caso tenhamos o tipo INCREMENT. Nesse caso, do redutor, retornamos currentCounter mais 1. Nós incrementamos o contador. Novamente, tudo o que está sendo retornado do redutor será definido como o novo estado. Caso tenhamos um decréscimo, dizemos currentCounter menos 1. Caso chamemos RESET, retorne 0. Caso nenhuma dessas corresponda por padrão, retornaremos 0. Vamos salvá-lo e vamos ver. Se eu clicar em Incrementar, o contador será incrementado. Se eu clicar em Redefinir, ele será redefinido para zero. Se eu diminuo, está sendo diminuído. Como você pode ver, usando essa função redutora e usando as ações que nós mesmos definimos e depois as manipulamos dentro da função de registro. Podemos alcançar essa lógica para gerenciar o estado com base em ações. E, novamente, essa é uma alternativa ao uso do gancho useState. Use o redutor da mesma forma que o estado manipula o estado, mas com o conceito de redutores e ações de despacho, qual deles usar. Depende do caso de uso e, na verdade, do que você preferir. mais comum é usar useState, mas digamos que se sua lógica para atualizar o estado inclua muitas ações, digamos, diferentes, como Incrementar, Diminuir, redefinir, definir um ações, digamos, diferentes, como Incrementar, Diminuir, redefinir, definir valor específico, digamos, Incrementar em 10, você possa ter sua lógica para atualizar o estado com base em ações específicas, você pode usar o gancho UseReducer. Por que estou dizendo tudo isso é porque, para implementar nossa lógica, Start Shows, usaremos o gancho redutor de usuário porque teremos algumas ações, como Start Show e OnStart Show. Anteriormente, mencionei que para essa ação você pode passar qualquer dado aqui. Vamos ver o que quero dizer com isso. Assim como eu disse, temos um único lugar onde lidamos com a lógica e tudo o que for retornado da função redutora será definido como o novo estado. Por que não definimos outra ação aqui chamada SET_VALUE, algo assim. Então, criarei outro botão aqui e direi a Set para, digamos, 500. Em seguida, clique em Definir como valor. Vou criar essa função aqui e despachar o tipo SET_VALUE para que ela possa ser tratada pelo redutor. Vou passar o valor, ou digamos, newCounterValue 500. Agora, como temos acesso ao objeto de ação dentro do redutor e sabemos que o objeto de ação é exatamente o que despachamos, podemos dizer que retorna action.newCounterValue. Tudo o que passarmos como newCounterValue será retornado da função redutora e será o novo estado. Vamos tentar ver Incrementar, Diminuir, Definir para 500, é 500, algo assim. Quaisquer dados que você passar aqui estão disponíveis dentro da função redutora. Basicamente, é isso. nada mais a acrescentar sobre redutores Talvez nada mais a acrescentar sobre redutores seja que você provavelmente já ouviu falar sobre redux, uma biblioteca para gerenciar o estado global em aplicativos React. Redux é baseado no conceito de redutor. Em um redux, você envia ações como essa e, em seguida, manipula todas elas dentro de redutores. Legal. Vamos nos livrar de tudo isso. Espero que tenha ficado claro por que o useReducer pode ser útil como uma alternativa ao useState. Na verdade, talvez eu acrescente que todas essas ações no incremento, no decréscimo, podem ser facilmente substituídas pelo gancho useState. Em vez de lidar com toda a lógica dentro do redutor, você pode simplesmente fazer algo como setCounter, digamos CurrentCounter mais 1. O mesmo que você pode fazer internamente em decréscimo. Desculpe-me, será assim, currentCounter menos 1. Basicamente, você escreveria a mesma lógica que você faz dentro do redutor. Quando você usa, useState hook e, se estiver reiniciando, bastaria saber o setCounter e talvez seja mais fácil. Depende. É por isso que é chamado de alternativa. Depende de você o que atenda às suas necessidades. Agora que conhecemos o UseReducer, podemos realmente usá-lo para implementar nossa lógica para iniciar shows. Legal. Nos vemos na próxima. 79. 23 Starred mostra p1: Ei, aí. No último vídeo, falamos sobre o UseReducer como uma alternativa ao gancho useState. Ele pode ser usado para gerenciar o estado quando temos várias ações definidas e gostaríamos de atualizar o estado com base em algumas ações. Vamos usar o UseReducer para implementar nossa lógica de estudo de programas. Vamos embora. Em primeiro lugar, como vamos gerenciar a lógica por trás dos programas estrelados? Sempre que clicarmos no botão “Iniciar”, adicionaremos show ID à matriz, que será nosso estado. O estado dos shows iniciais será apenas uma matriz de IDs de programas. Se clicarmos em um show, o ID será adicionado à matriz. Se clicarmos nele duas vezes, ele será removido dessa matriz. Então, sempre que vamos para a página inicial, pegamos essa matriz de shows estrelados e a usamos para consultar dados da API TV maze. Bem simples. A questão é: onde vamos escrever essa lógica? Temos um componente doméstico. No entanto, em todo o componente, que é exibido , mostre a grade ou grade real com base nos dados que temos. Vamos escrever a lógica dentro do show grid por enquanto e, mais tarde, vamos extrair essa lógica para um arquivo diferente. Será mais fácil acessá-lo dentro de outros componentes, por exemplo, o componente inicial, porque nossa lógica será compartilhada entre vários arquivos eventualmente. Vamos começar de forma simples. Dentro da grade de exibição, vou importar o UseReducer do react. Então eu vou ligar para você com, por enquanto, digamos, um redutor de programas estrelados que vamos criar em um segundo. Nosso estado inicial será uma matriz vazia. UseReducer retorna como uma matriz de dois elementos em que o primeiro elemento será o próprio estado, então starred é exibido e, em seguida, a função de despacho, digamos, dispatch start. Agora precisamos criar um redutor de shows estrelado, uma função que manipulará a lógica para atualizar o estado, bem como precisamos definir ações. Basicamente, teremos apenas duas ações aqui. Para começar um show e cancelar um show. Vamos defini-los. Sempre que clicarmos em me marcar como estrela, enviaremos uma ação do tipo start-me ou, digamos, start-me, e os dados passados serão mostrados como ID. A segunda ação será unstar. Novamente, vamos passar o show ID para o redutor. Dentro do redutor, o primeiro argumento é nosso estado atual. Vamos chamá-lo de início atual. O segundo argumento será um objeto, a ação que está sendo enviada. Então, aqui, usando novamente o caso do switch, escreveremos a lógica para lidar com as ações que estão sendo despachadas. Escrevemos a lógica com base no tipo de ação. Nós trocamos o tipo de ação. Caso tenhamos uma estrela, nesse caso, retorne currentStarred.concat a ação showId. Seja qual for o ID de exibição que passarmos pela ação, adicione esse valor à nossa matriz atual com estrelas. A segunda ação será a estrela com a qual vamos encarar. Nesse caso, precisamos remover esse ID de exibição de nossa matriz de estado atual. Podemos usar o método de filtro de pontos, que está disponível na matriz. Para elementos, então, antes de tudo, o método de filtro espera um retorno de chamada no qual escrevemos a lógica para filtrar elementos dentro da matriz. Esse método de filtro de pontos, assim como o mapa escuro, recebe exatamente os mesmos argumentos. primeiro elemento é valor, o elemento atual que percorremos do que o índice desse elemento e a referência à própria matriz, precisamos apenas do valor que será mostrado o ID. O que quer que esse filtro de pontos retorne, ele pode ser verdadeiro ou falso. Se esse retorno de chamada retornar verdadeiro para esse elemento , esse elemento permanecerá dentro dessa matriz Se o retorno de chamada retornar false para o elemento que percorremos, ele não será incluído na matriz final. Só vamos dizer se mostrar ID não é igual a ação mostrar ID. Com essa lógica, podemos filtrar todos os elementos que não atendem a essa condição. Por padrão, se passarmos algo desconhecido nesse caso, retorne o mesmo estado estrelado pelo padrão. Vamos aqui e criar uma função que manipulará a lógica quando clicarmos no botão “Star Me”. Vamos dizer a const on star, eu clico. Dentro dessa função, vamos escrever a lógica. Em primeiro lugar, ao me estrelar , clique será uma função que receberá show ID como argumento. Este será o ID de exibição, o ID de exibição correspondente com o botão Star Me. Ele se referirá a mostrar o ID no qual basicamente clicamos. Então, aqui dentro, precisaremos determinar se o programa já foi estrelado. Se o show não estiver marcado com estrelas, enviaremos a ação inicial, caso contrário, enviaremos a ação Desmarcar estrela. Podemos criar uma variável chamada starred e simplesmente perguntaremos se a matriz starred shows inclui show ID em que clicamos. Se esse programa for estrelado, nós vamos enviar estrelado. A ação será do tipo OnStar, e mostrar ID, precisamos passar o ID do show aqui, será o que chamarmos de OnStar me click width. Caso contrário, chamaremos dispatch starred do tipo star Agora, precisamos de alguma forma usar esse OnStarmeClick. Bem, podemos usar essa função dentro do ShowCard. Podemos, digamos, passar um argumento, passar um adereço chamado onStarClick e podemos passar o diretório onStarmeClick aqui, assim, ou digamos que onStartMeClick será onStarmeClick. Dentro do ShowCard, vamos pegar a sonda OnStarmeClick pela qual passamos agora. Você pode ver que esse onStarmeClick está sendo chamado com o argumento showID, o que significa que sempre que chamamos onStarmeClick, precisamos passar showID. Neste botão aqui, OnStarMe, vamos dizer ao OnClick, ligue para OnStartMeClick e passe o ID do programa. Legal. Agora, já temos o fluxo completo, vamos tentar cancelar log StarredShows para ver o que exatamente temos em nosso estado. Até agora, inicialmente é uma matriz vazia, é isso que definimos. Se eu clicar em StarMe, agora vejo que esse ShowID foi adicionado a esse estado. Muito legal. Vamos tentar adicionar outro. Agora podemos ver que temos três elementos. Se eu clicar no mesmo programa duas vezes, ele será removido da taxa estadual. Nossa lógica básica de estrelar e não estrelar programas funciona muito bem. No entanto, como esse gancho está dentro do componente ShowGrid, sempre que navegamos até Iniciar e, em seguida, vamos voltar para Início , nosso estado voltará ao inicial novamente, porque esse estado é local para aquele componente, quando o componente é desmontado, o estado desaparece. Precisamos pensar em como podemos realmente manter esses dados. Podemos fazer isso, digamos, salvando StarredShows no armazenamento do navegador para que mais tarde possamos recuperá-lo. Isso vai ser um pouco avançado porque a primeira coisa que me vem à mente quando precisamos compartilhar o estado entre várias páginas, entre vários componentes, podemos elevar esse estado, digamos, em algum lugar para talvez um aplicativo. Se tivermos nosso estado administrado aqui, esse estado então pode ser passado como um suporte para, digamos, componentes infantis para estrelar e para casa. Mas neste caso, elevamos tudo até o topo, para que todos, nosso componente raiz, saibam algo sobre esse estado. Isso não é ruim, e essa é uma maneira bastante padrão de gerenciar o estado de compartilhamento entre componentes no React. Mas vamos apresentar uma alternativa para isso. Por que vamos fazer isso dessa maneira e não elevar o componente de estado para aplicativo? Porque mesmo se compartilharmos o estado entre as páginas dentro do aplicativo, quando atualizarmos a página, esse estado desaparecerá. Mas não queremos fazer isso. Em vez disso, queremos manter o estado de alguma forma, então, sempre que atualizamos a página, nossos StarredShows ainda estão lá. Mesmo se fecharmos o navegador ou talvez fecharmos essa guia, nossos StarredShows não desaparecerão. O que vamos fazer nesse caso é usar algo chamado armazenamento de navegadores. Podemos usar especificamente o armazenamento local ou o armazenamento de sessão. É como um pequeno banco de dados que fica dentro do navegador e você pode usá-lo para armazenar dados temporários dentro do navegador. É um banco de dados do tipo valor chave, o que significa que, sob chave específica, você pode salvar um valor específico e, ao atualizar a página, ou, digamos, fechar o navegador e voltar para aquela página, para aquele URL específico, para aquele site específico, esse armazenamento é persistente. Os valores ainda estão lá, a menos que sejam limpos pelo próprio aplicativo ou manualmente por você, pelo usuário. Vamos armazenar nossa página inicial no armazenamento local. Vamos pensar em como podemos fazer isso. Precisamos pensar em como podemos gravar o estado que temos dentro do nosso aplicativo no armazenamento local. Precisamos sincronizá-lo, porque sempre que alteramos esse estado, também queremos salvá-lo no armazenamento local, salvá-lo no banco de dados e, quando atualizarmos a página, gostaríamos de recuperar os dados desse armazenamento e usá-los em nosso aplicativo. Com isso, podemos escrever, digamos, lógica adicional em cima do UseReducer. Para isso, podemos criar um gancho personalizado em cima do UseReducer com lógica extra que persiste no estado dentro do armazenamento local. Isso é um pouco avançado, mas não há nada, digamos, de confuso nisso. Vamos seguir em frente e tentar fazer isso. Já temos o gancho useReducer e queremos escrever a lógica que faz tudo exatamente da mesma forma que useReducer, mas também sincroniza o estado com o armazenamento local. Podemos criar um gancho personalizado chamado algo como UsePersistedReducer, talvez. Vamos fazer esse gancho personalizado na parte superior, vamos chamá-lo de UsePersistedReducer. Queremos manter a API do gancho embutido, o que significa que queremos usar exatamente os mesmos argumentos, queremos retornar exatamente os mesmos elementos, para que tudo seja praticamente o mesmo. Vamos seguir em frente e tentar fazer isso. Dentro de usePersistedReducer, vamos usar useReducer. Como esse gancho será, digamos, reutilizável, não queremos, digamos, unir digamos, reutilizável, não queremos, fortemente a lógica a StarredShows aqui, ele será algo, digamos, abstrato e reutilizável para lidar com vários casos de uso. Vamos apenas nomear esse patch como dispatch e, em vez de StarredShows, vamos chamá-lo de state. Então, dentro desse UseReducer, precisamos passar o redutor, pois vamos reter a API de usePersistedReducer. Na verdade, vamos usá-lo como useReducer, usePersistedReducer, vamos passar, digamos , um redutor, depois queremos passar a chave inicial e também queremos passar a chave de armazenamento local sob a qual os valores serão salvos aqui. Agora, como precisamos passar três argumentos, precisamos recebê-los dentro de usePersistedReducer, então recebemos reducer, receberemos initialState e receberemos localStorageKey. Passamos para UseReducer. No redutor, passamos initialState e passamos algo chamado initializer. O que é isso? Quando atualizamos a página, queríamos recuperar dados do armazenamento local e usá-los como nosso estado inicial. Queremos executar essa lógica apenas uma vez quando o componente é montado, para que possamos usar a função inicializadora. É o terceiro argumento que é executado apenas uma vez para inicializar initialState. Esse inicializador recebe um argumento, initialState. Basicamente, tudo o que passarmos aqui estará disponível como argumento dentro do inicializador. Isso é feito neste caso se o inicializador for criado como uma função separada em algum lugar externo. Nesse caso, não vamos fazer isso, vamos apenas embutir o inicializador diretamente aqui, que o chamará de inicial. Esse argumento inicial será basicamente apenas o estado inicial que passamos aqui. Agora, a lógica será a seguinte. Primeiro, precisamos verificar se já temos dados dentro do armazenamento local. armazenamento local está disponível no objeto da janela, digamos, uma variável global que significa que podemos simplesmente iniciar armazenamento local e, em seguida, aumentar, ele simplesmente funciona. Aqui, vamos perguntar a PersistedValue. Se o armazenamento local obtiver Item sob uma chave específica, precisamos primeiro entender se esse valor existe dentro da base da camada ou não. Talvez vamos brincar um pouco com o LocalStorage para que você tenha uma ideia. LocalStorage, podemos setItem sob uma visão específica da chave. Digamos que abaixo da chave baixa eu possa dizer valor alto. Eu executo essa lógica e volto para localStorage. Aqui, caso eu o atualize, você pode ver que, na tecla baixa, agora tenho um valor alto. Posso armazenar o máximo de valores aqui, posso reescrevê-los. Agora, como esse valor é armazenado no armazenamento do navegador, posso simplesmente chamar getItem e especificar a chave sob a qual eu queria obter meu valor. Eu especifico getItem low, recebi meu valor alto. O problema com o LocalStorage é que ele só pode funcionar com strings. Em nosso caso, o estado com o qual trabalhamos será uma matriz, o que significa que quando escrevermos em localStorage, converteremos nossa matriz em uma string e, quando recuperarmos tudo do armazenamento local, precisamos convertê-la de string em uma matriz novamente. Como podemos fazer isso. Em primeiro lugar, no LocalStorage obtemos Item em LocalStorageKey. Nosso valor persistente será nulo ou uma string. Nulo caso esse valor não exista dentro do armazenamento local, caso contrário, sempre será uma string porque localStorage novamente funciona apenas com strings. Aqui, tudo o que retornarmos do inicializador será definido como o estado inicial final. Tudo o que especificamos aqui vem como argumento para o inicializador e , em seguida, o inicializador decide qual será o initialState final. Se não tivéssemos esse inicializador, podemos simplesmente passar initialState e ele funcionará. Mas se trabalhamos com o inicializador e trabalhamos com o inicializador porque trabalhamos com o localStorage, adicionamos toda essa lógica em cima dele. Aqui, perguntaremos se o valor persistente é verdadeiro. Nesse caso, aplique o método JSON.parse. O que é JSON.parse? Temos uma matriz de, digamos, elementos 1, 2. Nós o convertemos em uma string usando o método chamado JSON.stringify. Agora nossa matriz se transformou em uma string e, quando recuperamos do localStorage, esse valor persistente será essa string. Agora precisamos converter essa string volta em objeto, de volta em matriz. Podemos usar JSON.parse em vez de JSON.stringify para desserializar nosso valor de localStorage e podemos ver que temos um inesperado, não branco. Como isso já é um objeto, ele tem que ser uma string, então digamos que passamos uma string que é essa matriz e ainda temos esse problema; não é um JSON válido. O que está acontecendo? Provavelmente quer que eu use isso. Vamos ver. Agora, eu passo a string válida e você pode ver que ela analisou a string de volta para a matriz. Agora, essa estrutura de dados tem o tipo de matriz, não apenas uma string. Espero que faça sentido. Aqui analisamos persistedValue, caso contrário, se persistedValue for nulo, se o valor não existir, use o valor inicial, que será o initialState. Agora, finalmente terminamos com a lógica de inicializar o estado de quando a página está sendo atualizada ou quando voltamos à página. Legal. Agora, precisamos também sincronizar as atualizações de estado dentro do gancho UsePersistedReducer em que trabalhamos. Podemos usar o UserEffect porque você lembra UserEffect nos permite conectar-se ciclo de vida do componente e executar a lógica quando algo muda. Vou importar UserEffect e, a partir daqui, chamarei UserEffect e passarei a matriz de dependências na qual vou especificar. Se nosso estado mudar , assim como se nossa chave; localStorageKey mudar, nesse caso, execute esse retorno de chamada. Novamente, se os estados mudarem ou se localStorageKey mudar, chamamos essa função. Essa função sincronizará o estado com localStorage, então vamos informar LocalStorage.set. A chave do item será localStorageKey e o valor será state. No entanto, precisamos transformá-la em uma string antes de podermos gravar em localStorage. Vamos chamar o estado JSON.stringify. No final desse gancho, queremos que ele retorne uma matriz de exatamente dois elementos para que nosso redutor usePersisted de gancho redutor usePersisted se pareça com o gancho useReducer original. Nós vamos contar [inaudível]. Declare e devolva esses pacotes e pronto. Este será nosso último gancho. É basicamente apenas uma lógica extra em cima do useReducer integrado que sincroniza o estado com o localStorage. Assim como eu disse, é um pouco avançado, no entanto, se você der uma olhada na verdade não há nada complicado aqui. Agora, em vez de usar useReducer, aqui dentro do ShowGrid chamaremos usePersistedReducer e, como chave do terceiro argumento, diremos StarredShows. Agora vamos tentar ver. Se voltarmos ao aplicativo, vamos abrir o armazenamento local do aplicativo. Vamos limpar isso por enquanto, vamos procurar shows. Você pode ver que, assim que o componente é montado na página, esse gancho usePersistedReducer é executado, o estado é inicializado, pois nosso estado muda e o useEffect é executado pelo menos uma vez. Ele já começou a sincronizar o estado com o localStorage aqui. Em key start shows, colocamos nossa matriz vazia, nosso initialState. Se eu tentar fazer algo bombar, mostrar é editar aqui. Está sincronizado. Se eu clicar em “Me marcar como estrela” em outra coisa, ela sempre será sincronizada com LocalStorage, o que significa que funcionou. Incrível. Por enquanto, acho que isso vai ser bom porque, bem, acho que é o suficiente por enquanto. No próximo vídeo, falaremos sobre como podemos prosseguir com essa lógica, para que possamos, de alguma forma mostrar se esse programa é estrelado ou não. De alguma forma, diga visualmente ao usuário que esse programa já começou e , em seguida, provavelmente buscaremos todos esses dados dentro da página marcada como favorita. Por enquanto, vamos comprometer isso; o que já temos, para não perdermos as mudanças. Aqui vou dizer adicionei lógica inicial para estrelar shows com UseReducer. Foi criado UsePersistedReducer para sincronizar o estado com o LocalStorage. No próximo vídeo, vamos continuar com isso. Nos vemos lá. 80. 24 Starred mostra p2: Olá. No último vídeo, começamos a trabalhar na funcionalidade com estrelas. Criamos um redutor persistente de uso de gancho personalizado, que sincronizou nosso estado StarredShows com o armazenamento local para que, sempre que o atualizarmos, possamos reinicializar o estado a partir do armazenamento local. Eu não mostrei isso no vídeo anterior, mas se tentarmos cancelar log StarredShows se eu atualizar a página, vou voltar para casa. Se eu atualizar a página e quando o componente for montado, nosso estado inicial será recuperado do armazenamento local, o que quer que tenhamos aqui. Se limparmos tudo, se removermos tudo do armazenamento local, atualizarmos a página e procurarmos shows, nosso estado padrão é uma matriz vazia. Legal. Agora precisamos pensar em como podemos realmente, digamos, reutilizar esse gancho em várias páginas, inicial e no início. Mas primeiro, vamos dizer ao usuário se esse programa foi iniciado ou não. Vamos voltar para o ShowGrid aqui e para o ShowCard, podemos passar outro adereço chamado isStarred. Isso é Starred será bem simples, vamos apenas perguntar se StarredShows. Indique que incluímos esse ID de demonstração de dados. Portanto, isStarred será um booleano que indicará se esse show já está presente dentro da matriz starredShows. Então, dentro do ShowCard, vamos pegar IsStarred como adereço. Por enquanto, vamos perguntar se esse programa já foi estrelado, por favor, exiba-me no Star me, por favor, ou apenas Unstar me ou Star me. Vamos tentar ver. Sempre que eu clico aqui, ele se transforma em Unstar me star. Se clicarmos em “Olá amanhã” , ainda será Unstarme. Agora, se eu atualizar a página, procuro olá novamente. Se eu rolar, você verá que os valores estão sendo persistidos. Mesmo que eu feche meu navegador, feche esta guia e volte para aquela página novamente para ver os programas específicos, eles ainda mostrarão Unstar me porque novamente sincronizamos o estado com o armazenamento local. Legal. Agora vamos prosseguir e extrair lógica que escrevemos aqui do ShowGrid em um arquivo separado, para que posteriormente possamos reutilizar a mesma lógica dentro da página inicial. Vamos embora. Provavelmente dentro do código-fonte ou talvez vamos criar uma nova pasta chamada library, abreviadamente lib. Aqui vamos criar um arquivo chamado UseStarredShows. Dentro desse arquivo, vou colocar toda essa lógica relacionada aos ganchos que escrevemos anteriormente. Isso será usePersistedReducer, isso será StarredShowsReducer, essa será essa chamada usePersistedReducer e a importação de useReducer e useEffect. Então, se quiséssemos, digamos, usar exatamente o mesmo gancho dentro de outro componente, digamos, dentro das páginas marcadas com estrela, simplesmente copiaríamos assim. Precisamos chamar UsePersistedReducer novamente, precisamos passar StarredShowsReducer novamente, especificar a mesma chave, mas podemos dar um passo adiante, podemos criar outro gancho personalizado em cima disso e, digamos, ocultar a lógica lá. Dentro de useStarredShows, criaremos um novo gancho chamado useStarredShows e esse gancho chamaremos usePersistedReducer e, em vez de apenas valores de destruição aqui, retornaremos qualquer valor que usePersistedReducer aqui retorne. Aqui provavelmente não vamos passar nada porque queremos, digamos, ocultar a lógica logo por trás desse gancho, então, dentro de nosso componente, podemos simplesmente chamar useStarredShows e realmente salvá-lo, depois exportá-lo de useStarredShows e importá-lo da biblioteca UseStarredShows e o gancho será useStarredShows. Chamamos isso e simplesmente obtemos StarredShows e simplesmente recebemos DispatchStarred. Você pode ver agora que parece muito, muito mais limpo do que antes. Agora também é reutilizável, o que significa que dentro do componente favorito podemos fazer exatamente o mesmo, basta chamar useStarredShows e descartar os mesmos dados. Vamos fazer isso. Dentro de starred, vou importar useStarredShows e aqui provavelmente não precisaremos de dispatchStarred, não precisaremos da função de despacho, então não vamos desestruturá-la, vamos pegar apenas o primeiro elemento, o StarredShows. Agora, aqui podemos escrever a lógica para creditar os dados, vamos fazer isso no próximo vídeo. Por enquanto, provavelmente vamos acessar a página com estrela, estrelada, StarredShows.length, que exibirá o número de programas que estrelamos até agora. Vamos tentar ver se funcionou. Se formos para a página inicial, podemos ver que temos dois programas com estrela, isso é o que vemos em nosso estado que persiste no armazenamento local. Se tentarmos limpar o armazenamento local e atualizarmos a página, a estrela será zero porque removemos tudo, o estado foi reinicializado, algo assim. Por enquanto, vamos comprometer tudo o que fizemos aqui. Extraímos a lógica do gancho em um arquivo separado e criamos outro gancho personalizado em cima do nosso usePersistedReducer para StarredShows especificamente e o chamamos de useStarredShows. Em seguida, usamos esse gancho personalizado interno, com estrela, para exibir, por enquanto, o número total de programas que adicionamos e usamos esse gancho dentro de ShowGrid, useStarredShows, bem como o usuário visualmente notificado, exibindo textos com estrela me ou não com estrela com base no ID do show, esteja ele dentro da matriz de estados ou não. Na verdade, pareceu muito. No entanto, não foi muito, não é? Então eu adiciono tudo ao estágio e digo que criei useStarredShows, gancho personalizado colocou toda a lógica do gancho, colocou tudo ou, digamos colocou a lógica de gancho useStarredShows em um arquivo separado. Diga ao usuário se o programa está marcado ou não. Diga ao usuário se o programa está marcado ou não. É isso. Vamos para o GitHub e nos vemos na próxima. No próximo vídeo, vamos buscar todos esses programas quais temos acesso dentro do componente inicial. Agora, vamos buscá-los na API de criação de TV e exibi-los finalmente. Te vejo. 81. 25 Starred mostra p3: Olá. Neste vídeo, finalmente terminaremos a página do programa estrelado. No vídeo anterior, criamos um gancho personalizado chamado user starred shows, que é um gancho sobre o redutor persistente de uso, que também é um gancho personalizado sobre o redutor de uso , mas com lógica extra que sincroniza o estado com o armazenamento local. Neste vídeo, pegamos os programas com estrelas que temos dentro do componente marcado com estrela e os buscamos na API TVMaze. Em primeiro lugar, temos uma série de IDs de shows. Se examinarmos a documentação do TVMaze, não temos nenhum endpoint. Experimente e procure onde possamos assistir vários shows ao mesmo tempo. Então, em nosso caso, enviaremos várias solicitações para a API. Vamos para o componente estrelado. Aqui, por padrão, usaríamos o efeito de uso para capturar dados da API somente quando o componente é montado, mas agora, como usamos a biblioteca de busca de dados, use query, podemos usá-la para capturar dados. Deixe-me copiar isso do componente inicial, eu vou aqui, dentro starred eu importo use query da biblioteca de consultas React. Agora, nossa chave de consulta será marcada com estrela e passaremos a matriz de programas com estrela que temos como chave de consulta. Então, dentro da função de consulta, precisamos obter todos os nossos programas. Como podemos fazer isso? A primeira e ingênua abordagem é que podemos realmente usar o for-loop simples, depois percorremos cada programa que temos dentro da matriz de shows com estrela, pegamos cada ID de show e, em seguida, enviamos a solicitação. No entanto, você pode ver que todas essas solicitações que podemos enviar, digamos que temos dois IDs de exibição dentro do estado e enviaremos duas solicitações. Quando pudermos passar por cima de cada elemento , ele enviará a primeira solicitação, somente quando terminar , enviará a segunda solicitação. Isso não é eficiente porque as solicitações que enviaremos para shows não dependem umas das outras. Queremos que isso aconteça o mais rápido possível. É por isso que precisamos enviar várias solicitações ao mesmo tempo. Para alcançar esse comportamento, vamos usar promise.all. Deixe-me mostrar o que quero dizer. Dentro da função de consulta, vamos escrever a seguinte lógica. Antes de fazer isso, vamos remover a opção ativada e continuaremos atualizando o Window Focus. Aqui, a lógica será a seguinte. Que seja apenas uma função e uma função de sincronização. Aqui vamos primeiro mapear nosso, onde está? API TVMaze. Esta função Get Show by ID. Vamos mapear essa função que retorna a promessa em uma matriz. Já parece complicado, mas deixe-me mostrar o que quero dizer. O que faremos aqui. Vamos dizer, digamos, promessas de solicitação de API. Faremos starredshows.map. Vamos mapear o show ID para a API para que seja exibido por ID dessa forma. Vamos especificar o ID do show aqui. Com essa abordagem, acabaremos com uma série de promessas. Porque mapeamos cada ID do programa para ser exibido por ID, o que retorna uma promessa. Eventualmente, acabamos com uma série de promessas. Para lidar com uma série de promessas e garantir que essas solicitações sejam tratadas, digamos que em paralelo ao mesmo tempo, podemos usar o método promise.all. Vamos contar await promise.all. Na verdade, podemos, você sabe o que, mover toda essa lógica daqui para uma função reutilizável dentro do TVMaze.gs. vamos contar os shows por Desta vez, vamos contar os shows por IDs e receberemos os IDs dos programas aqui. Em vez de apenas fazer a API Get Here, vamos transformar essa função em uma função de sincronização e colocaremos a lógica que escrevemos aqui dentro de get show by IDs. Vamos mapear cada ID de show para uma promessa, depois dentro de promise.all, e já vemos que essa promessa não está definida vindo do ES lint, na verdade. Bem, isso é interessante. Suponho que seja porque dentro do ES lint RC precisamos instruir o ES lint a entender que usamos a sintaxe mais recente do JavaScript , a moderna, então vamos dizer que o ES6 será verdadeiro. ES6 significa ECMAScript versão 6 e superior. Agora, acho que não temos nenhum erro, isso é verdade. Para promise.all, vamos aprovar promessas de solicitação de API ou vamos chamá-las de promessas para simplificar as coisas. O que o promise.all faz é resolver uma série de promessas em paralelo, e elas são resolvidas uma só vez e tratadas em paralelo. baixo do capô, parece promessa 1, promessa 2, promessa 3 de prometer. Tudo de novo, uma série de promessas. Promise.all resolve todos eles de uma vez. Em seguida, prometa.all resultados.all para uma matriz de valores resolvidos. Se tivermos uma série de promessas, digamos que promessa 1, promessa 2, promise.all resolva todas elas de uma vez. Promise.all retorna uma matriz de valores resolvidos. Se a promessa 1 for resolvida para, digamos, valor 1, receberíamos uma matriz com, digamos, o valor resolvido 1. Eles prometeram resolver outra coisa, nós receberíamos resolução, valor resolvido 2. Se a promessa não resolver em nada, talvez para nula, para um valor indefinido seria indefinido ou nulo. Mas o pedido foi mantido. Qualquer ordem presente aqui na mesma ordem, as promessas são resolvidas ao usar promise.all. Um ponto aqui, promise.all também retorna uma promessa, então precisamos evitá-la. Isso é importante. Agora, podemos chamá-lo de resultado. Aqui fazemos promessas e retornamos o resultado. Como no nosso caso, cada promessa resolverá mostrar dados, eventualmente receberemos uma série de promessas resolvidas, o que significa que receberemos uma série de programas. Vamos registrá-lo no console apenas para ver com o que exatamente trabalhamos. Dentro da inicialização J6, vamos chamar isso de get show by IDs. Talvez, você sabe o que? Dentro do get show by ID, incorporamos dados. Mas dentro da página inicial, não precisamos dela. Em vez de chamar get show by ID aqui, vamos apenas chamar o ApiGet sem a parte incorporada. Algo parecido com isso. Agora, dentro da página com estrela, vamos especificar: ligue para obter shows por IDs. função de consulta interna e a passagem interna com estrela mostram o que temos. Agora teremos um erro estrelado e marcado com estrela. Não nos confunda com nomeação. Provavelmente vamos chamá-lo de programa estrelado, IDs de programas estrelados. Aqui, serão apenas StarredShows e StarredShows à prova de erros. Agora vamos aplicar renderização condicional simples aqui, assim como fizemos anteriormente na página de exibição com if e if you turn. Vamos perguntar se StarredShows é realmente verdadeiro. Nesse caso, retorne ShowGrid porque usamos show grid para exibir todos os programas que temos, então o que usará o ShowGrid, mas primeiro precisamos importá-lo. Importe ShowGrid. Ele já é preenchido automaticamente para mim a partir dos componentes, mostra ShowGrid. Se começarmos os shows, retornaremos o ShowGrid e o ShowGrid espera que passemos os shows aqui. Vamos tentar fazer isso, os programas são iguais aos StarredShows escolhidos e, por padrão, fim de semana e exibem olá. Vamos primeiro tentar ver o que temos. Nosso aplicativo não está funcionando porque não iniciamos o servidor div ok, agora temos nossos programas vamos tentar adicionar algo estrelado para mim. Agora vamos para a página inicial e pronto, temos uma tela em branco e, se olharmos dentro do console, vemos que não é possível ler as propriedades do ID de leitura indefinido. O que acontece se olharmos para dentro do ShowGrid? Onde está? Recebemos shows, que deveriam ser uma matriz e, dentro dessa matriz, cada elemento tem a chave.show property.show mas examinaremos nosso resultado e é isso que o console faz login, é mostrado por IDs aqui. Você pode ver que temos uma matriz de elementos e cada elemento da matriz não tem o. mostrar propriedade. Precisamos consertá-lo de alguma forma. Precisamos ajustar essa forma de dados à forma de dados que se espera que seja usada dentro do componente. A questão é: onde exatamente precisamos fazer isso? Essa é uma boa pergunta. Bem, se quisermos tornar essa função, digamos, reutilizável possível em nosso caso, em nosso aplicativo, isso não é verdade, mas ainda assim, uma boa prática fazer as alterações necessárias somente onde elas são necessárias e se quisermos torná-las reutilizáveis, não queremos, digamos, modificar de alguma forma a forma dos dados aqui. Vamos fazer essa lógica dentro da função de consulta. Aqui em GetShowsByIds, não preciso mais registrar o resultado no console ou, na verdade, vamos mantê-lo por enquanto e, mais tarde, nos livraremos disso. Mas dentro da função de consulta aqui, faremos o seguinte. Quando getShowsByIds a promessa for resolvida, usaremos a sintaxe do ponto com essa agora porque ela se encaixará melhor Vamos ver essa sintaxe que temos aqui. Em vez de usar async await, podemos remover async daqui Assim, quando essa solicitação getShowsByIds terminar quando a promessa for resolvida com esse resultado, o que faremos, mapearemos cada elemento da matriz e aninharemos quaisquer dados que tenhamos aqui sob a chave show , sob a propriedade show , para que correspondamos à estrutura esperada ser usado pelo ShowGrid porque precisamos de uma matriz de elementos em que cada elemento tenha a propriedade show dentro. O que faremos, contaremos o resultado. mapa, obteremos os dados de exibição aqui e, a partir desse retorno de chamada, que retornará showData para torná-lo mais simples. Em vez de usar a sintaxe mais longa com return, diremos para retornar showData com colchetes. Agora, se tentarmos cancelar o log StarredShows aqui, ainda teremos esse problema. Deixe-me ver. Temos ShowData. Isso ocorre porque mapeamos que você pode ver cada elemento da matriz tem a chave ShowData, mas esperamos que ela seja apenas mostrada. Aqui, em vez de mostrar dados, podemos usar mostrar e mostrar. Agora vamos tentar ver se atualizamos e explodimos, tudo funciona magicamente agora. Se analisarmos o resultado, temos esses dados que recebemos do getShowsByIds e depois mapeamos os dados. Na verdade, aninhamos esses dados sob a chave show dentro de cada elemento da matriz, algo assim. Agora podemos finalmente remover esse resultado daqui e simplesmente retornar promise.allpromise. Aqui não precisamos mudar nada, essa é a nossa lógica aqui. Agora precisamos lidar com o caso quando não temos nenhum programa estrelado. Digamos que eu limpe o armazenamento local, atualize a página, nada seja exibido, mas, idealmente, queremos dizer ao usuário que, ei, não temos nenhum StarredShows. Já escrevemos essa condição if, que funcionará tanto se tivermos shows quanto se não tivermos shows, porque uma matriz vazia também é um valor verdadeiro, então podemos apenas dizer se starredShows.length é maior que zero se tivermos pelo menos um show e usamos o encadeamento opcional aqui porque nosso estado inicial será indefinido pela consulta de uso. Bem, a solicitação não acontece imediatamente, então esse StarredShows pode ser indefinido e não gerar nenhum erro, por exemplo, deixe-me remover isso, eu o atualizo, vou para console e vejo que não consigo ler propriedades de undefined, porque inicialmente, esse estado é indefinido novamente, a solicitação não acontece imediatamente. Podemos usar o encadeamento opcional aqui ou podemos perguntar se starredShows é verdadeiro e, usando o operador add, esse starredShows, nesse momento será definido, podemos digitar com segurança starredShows.length, mas para simplificar isso, usamos o encadeamento opcional. Se o comprimento de StarredShows for maior que zero, exibimos showGrid e adicionamos outra condição na parte superior. Se o comprimento de StarredShows for igual a zero. Nesse caso, exibimos div algo como se nenhum programa tivesse sido marcado com estrela. Em seguida, adicionaremos outra condição caso tenhamos algum erro. Se tivermos iniciado shows adder, informaremos que ocorreu um erro e diremos StarredShowsError.message. Por padrão, se nenhuma dessas condições for mantida nesse caso, estamos dizendo que os programas estão parados ou que apenas os programas estão carregando. Este é o nosso mercado final, por enquanto, vamos tentar ver. Se eu atualizar rapidamente, você verá um piscar de olhos porque, inicialmente, esse estado é indefinido, o que significa que por um curto período de tempo, essas condições não corresponderão e veremos os programas sendo carregados. Se a solicitação demorar mais do que o esperado, veremos que os programas estão carregando e veremos que nenhum programa foi marcado como estrela. Se formos para casa, procuramos programas em que estrelamos alguns programas aqui, este, depois procuramos outra coisa, como, ei cara, ei, voltamos a estrelar você pode ver agora que temos esses programas aqui. Mesmo se atualizarmos a página, os programas ainda estão lá. Muito legal. Agora temos o ciclo completo e completo dessa funcionalidade estrelada. Parabéns. Por enquanto, é isso mesmo, vamos adicionar todas as mudanças ao palco. Primeiro, instruímos ao ES link que estamos usando JavaScript moderno para que não haja nenhum erro ao escrevermos construtor de promessa como este. Adicionamos outra função aqui para buscar todos os programas, conhecendo os IDs dos programas. Usamos o método promise.all para lidar com todas as solicitações ao mesmo tempo, porque essas solicitações não dependem umas das outras, elas precisam ser tratadas em paralelo e resolvidas de uma só vez É exatamente isso que promise.all faz. Em seguida, dentro do componente estrelado, usamos o gancho de consulta use para buscar dados. Já sabemos o que ele faz e por que os usamos. Em seguida, aplicamos a renderização condicional para exibir dados. É isso. Ótimo. Vamos confirmar tudo e digamos que buscado, estrelado mostra dados e exibição. ShowGrid para eles. Legal. Eu envio tudo para o GitHub e, com essa boa nota, nos vemos na próxima. 82. 26 atribuição: Olá novamente, tenho outra pequena tarefa para você lembrar que para implementar, o Start mostra que os dados persistem dentro do navegador. Quando atualizamos a página, nosso estado ainda está lá. Usamos armazenamento local, armazenamento dentro do navegador que pode persistir dados. Não seria bom se também pudéssemos persistir o que digitamos dentro da caixa de pesquisa, dentro do componente inicial. Então, se eu atualizar a página, tudo o que está dentro da caixa de texto ainda estará lá. A ideia aqui é praticamente a mesma. Então, se para começar, criamos nosso próprio gancho que sincroniza o estado chamado redutor persistido de fusível. podemos criar um arco muito semelhante, chamado Desta vez, podemos criar um arco muito semelhante, chamado de estado persistente de Hughes no topo do estado dos EUA, e então usar esse estado para implementar essa data na caixa de pesquisa. Esta é a tarefa para você. Vá em frente e tente isso. E desta vez, em vez do armazenamento local, talvez você possa usar o armazenamento de sessão. A diferença entre armazenamento local e armazenamento de sessão é que o armazenamento local persiste os dados, mesmo que você feche a guia e feche o navegador, armazenamento da sessão só persiste os dados até você fechar a torneira, fechar a guia e voltar para a página. Novamente, o armazenamento da sessão estará vazio, ou seja, pode ser mais adequado para a caixa de texto, porque não é algo que gostaríamos de salvar quando fechamos a guia ou fechamos o navegador. Portanto, a API não é a mesma, o que significa que, em vez do armazenamento local, você gravará o armazenamento da sessão e o resto permanecerá o mesmo, obterá o item e o item do site. Então, vá em frente e tente criar esse estado de uso persistente e, em seguida, implemente para manter o estado da caixa de pesquisa. Boa sorte com esse. Nos vemos na próxima. 83. 27 Implementando o uso de gancho personalizado usePersistedState: Olá de novo, como foi sua tarefa? Você conseguiu alcançar o que queríamos? Você conseguiu manter os dados dentro do armazenamento da sessão? Vamos ver. Se voltarmos ao formulário de pesquisa, aqui temos aquela chamada de estado de uso para ter o estado da string de pesquisa. Agora, se quisermos persistir no armazenamento local ou no armazenamento da sessão, precisamos escrever uma lógica extra. Podemos extrair toda essa lógica em algum lugar dentro de outro arquivo e, aqui, dentro do formulário de pesquisa simplesmente chamaríamos use persisted ou talvez use search string, que nos retorna novamente uma matriz de dois elementos, string e string de pesquisa, para que não alteremos a API do use state hook. Será praticamente o mesmo. Vamos seguir em frente e implementar tudo isso. Na pasta da biblioteca que tenho aqui, onde está localizado o uso start chose, vou criar um novo arquivo chamado use search, STR, search string. Aqui vou exportar const, usar a string de pesquisa. Nosso gancho não aceitará nenhuma discussão, vamos lidar com tudo interno, então o estado inicial será definido pelo gancho interno. Não queremos nos preocupar com isso sempre que usamos esse gancho. Então eu o guardo por enquanto. Então, a partir daqui, vou importar da biblioteca e usar a string de pesquisa. A aparência final será essa. Praticamente o mesmo que tínhamos anteriormente, mas com toda a lógica, agora vamos entrar. Em caso de uso, o início mostra semanalmente auxiliado aquele gancho personalizado chamado redutor persistido de uso. Podemos fazer exatamente o mesmo com estado de uso, mas em vez do redutor de uso, vamos usar o estado de uso. Vou comentar isso para referência. Use novamente um fatorável, necessário para sincronizar esse estado com o armazenamento da sessão. Vou precisar do seu estado e aqui vou criar um estado persistente de uso. Usar estado persistente receberá o estado inicial como argumento. Aqui, vou chamar o estado de uso e passar o estado inicial aqui. Mas, diferentemente do use reducer, use state pode receber o estado inicial como argumento ou a função inicializadora, que será executada apenas uma vez para inicializar o estado. No caso do redutor de uso, era o terceiro argumento no caso de alguns estados, ainda é o mesmo argumento, mas basta passar o retorno de chamada para lá. Aqui dentro, a lógica será praticamente a mesma que fizemos com o armazenamento local. Em primeiro lugar, nos referimos ao armazenamento da sessão, obtenha a chave de armazenamento local do item. Precisamos obter essa chave de armazenamento local aqui. No nosso caso, será a chave de armazenamento da sessão. Vamos tirá-lo do uso de argumentos estatais persistentes. Ao lado do estado inicial, podemos passar a chave de armazenamento da sessão. Então, novamente, temos um valor persistente; se o valor existir, nós o desoralizamos da string, caso contrário, usamos o valor inicial que passamos, que será o argumento inicial do estado. Incrível. Aqui recebemos a função de atualização de estado e estado. Então, exatamente a mesma lógica com efeito de uso. Vamos partir daqui e dizemos que, sempre que o estado mudar ou sempre que a chave de armazenamento da sessão mudar, chame o item do conjunto de pontos de armazenamento da sessão, a chave de armazenamento da sessão JSON, stringify, state. Então, a partir do estágio persistido de uso, novamente para manter exatamente a mesma API do use state hook, retornaremos uma matriz de dois elementos em que o primeiro elemento é o estado e o segundo é a função de atualização de estado. Agora, podemos remover esses comentários aqui e dentro de usar a string de pesquisa. Podemos chamar use persistent state, dentro de passarmos o estado inicial, será uma string vazia e a chave de armazenamento da sessão será uma string de pesquisa. Incrível. Agora, qualquer que seja esse uso, o estado persistente retorna e ele retorna uma matriz de dois elementos em que o primeiro elemento é o estado, segundo é a função de atualização de estado, exatamente a mesma API do use state hook. Em vez de escrever isso e, em seguida escrever state return e set state, podemos simplesmente retornar o que a função de uso persistente retorna. Retorne, use o estado persistente. Agora, é isso. Agora podemos usar esse gancho que criamos dentro do formulário de pesquisa e ele funcionará magicamente. Vamos tentar ver. Se eu atualizar a página, você poderá ver que, dentro do armazenamento da sessão, tenho uma string de pesquisa de chave, tudo o que especificamos aqui como a chave de armazenamento da sessão, para que o estado seja inicializado com o valor que passamos aqui por padrão como uma string vazia. Agora, o que quer que digitemos dentro da caixa de pesquisa, ele será desviado como valor dentro da chave de armazenamento da sessão na string de pesquisa, porque usamos o efeito para sincronizar o estado. Se eu atualizar, você poderá ver que tudo o que temos dentro do armazenamento da sessão agora está sendo exibido como estado inicial dentro da caixa de texto, se eu atualizar. Isso é muito conveniente, por exemplo, se eu acidentalmente atualizar a página, espero que faça sentido. Não é muito complexo como você pode ver, e eu realmente espero que você tenha implementado praticamente a mesma lógica. Por enquanto, vamos confirmar tudo e dizer que esse foi o uso do gancho de caracteres de pesquisa, a mensagem de confirmação será persistida na terceira forma, valor da caixa de texto no armazenamento da sessão. Toda a lógica em uso, busca, cadeia de caracteres, gancho. Eu envio tudo para o GitHub. Nos vemos na próxima. 84. 28 Introdução aos componentes estilo: Olá. No último vídeo, eu diria que terminamos toda a nossa lógica dentro do aplicativo. Agora é a hora de falarmos sobre estilos. Como vamos estilizar o aplicativo. Neste vídeo, falaremos sobre a abordagem que vamos adotar e aqui está um spoiler para você, a abordagem será sobre componentes estilizados. Neste vídeo, veremos como os componentes estilizados funcionam. Por que exatamente os escolhemos e, no final, compararemos os componentes estilizados a forma tradicional de vender aplicativos apenas com estilos CSS comuns. Vamos embora. O que são componentes estilizados? Essa é apenas uma biblioteca para estilizar ou reagir aplicativos com uma abordagem chamada CSS-IN-JS. CSS em JavaScript é uma abordagem que nos permite escrever marcação CSS com a ajuda do JavaScript. momento, estou no site oficial dos componentes de estilo, documentação oficial. O que faremos agora neste vídeo, analisaremos o básico para entender exatamente como poderemos usar essa biblioteca. Se eu rolar um pouco para baixo, passarei pelo processo de instalação simples. Voltarei à minha inscrição. Vou abrir uma nova instância de terminal aqui e executar componentes com estilo npm install. Depois de instalado, vou simplesmente fechar a instância. Eu fiz isso apenas para não interromper o aplicativo em si. Agora, temos componentes estilizados que aparecem no pacote Jason. Dependências dentro da documentação, podemos ver seu primeiro componente estilizado. Precisamos importar estilos de componentes estilizados e, em seguida, usar algo assim. Vamos para o componente inicial e podemos aplicar com componentes estilizados aqui na página inicial. Na parte superior, vou importar estilos de componentes estilizados. Em seguida, farei styled.button e, no final deixarei marcações vazias para ele. Agora, o que é isso? Ao chamar style, elemento style.HTML que você tem nessa lista muito longa, você pode criar, digamos, o elemento subjacente que você deseja estilizar, por exemplo, botão estilizado. A partir desse elemento, os componentes estilizados criarão um componente e esse componente terá estilos. Se voltarmos à documentação e rolarmos um pouco para baixo, aqui encontraremos este exemplo básico, style.button back-ticks e, em seguida marcação CSS. Como você pode ver, marcação CSS é escrita dentro de back-ticks. A propósito, o destaque da sintaxe que você pode ver aqui vem da extensão VS Code, que é chamada de componentes no estilo VS Code. Se você quiser que sua sintaxe seja destacada e preenchida automaticamente, instale essa extensão. Somos capazes de escrever CSS aqui dentro de back-ticks. componente estilizado usará o elemento de botão e basicamente apenas pegará elemento de botão HTML nativo e aplicará esse elemento de botão HTML nativo e aplicará esses estilos que escrevemos aqui em cima dele e, no final, produzirá o componente de botão que podemos usar dentro de nossa marcação. Vamos tentar. Dentro da marcação, vou usar esse componente de estilo de botão que foi criado e dizer olá aqui. Eu o guardo. Eu volto para o meu aplicativo e o que temos aqui? Se olharmos para dentro da marcação, temos esse lindo botão estilizado aqui com esse nome de classe exclusivo. Todos os estilos foram mesclados e vamos detalhar o que temos aqui. Em primeiro lugar, esse componente de botão renderiza elemento de botão HTML exatamente o que especificamos aqui como o elemento base para aplicar estilos, que significa que esse componente de botão aqui basicamente renderiza o elemento de botão HTML nativo, o que significa que todos os adereços que esse styled.something tem, podemos passar diretamente para esse componente. Se o elemento do botão tiver um atributo chamado tipo, podemos passar o tipo aqui. Se eu salvá-lo, você verá que ele será refletido. Eu tenho o botão de digitação agora, exatamente o mesmo que você fará com qualquer atributo HTML normal, digamos, nativo no elemento do botão, se você quiser que ele passe algo como um clique, ou se você quisesse passar algo como atributos de dados, algum atributo personalizado , você faria isso e funcionaria. Legal. Agora, temos esse nome de classe exclusivo aqui. O que é isso e por que parece tão estranho? O fato é que esses blocos que você escreve aqui especificamente para esse elemento têm como escopo apenas esse elemento, o que significa que esses estilos são exclusivos. Esse nome de classe é exclusivo e foi gerado automaticamente por componentes estilizados. Componentes estilizados garantem a exclusividade das classes que você escreve para esse elemento. Se eu criar outro componente estilizado, que parece exatamente o mesmo, mas tem um nome diferente, não importa. Pode ser, digamos, qualquer coisa, e então eu uso esse componente de qualquer coisa ao lado desse componente de botão, eles têm exatamente os mesmos estilos. Eles parecem visualmente iguais. Mas se você comparar os nomes das classes, eles são diferentes. O que os componentes estilizados fizeram , gerou um nome de classe exclusivo com base nesses estilos. Novamente, os componentes estilizados criam estilos exclusivos com escopo local , especificamente para o elemento. Faz sentido? Eu acho que sim. Também temos aqui um estilo dinâmico disponível para nós. Se voltarmos à documentação, se rolarmos para baixo, aqui, podemos encontrar outro exemplo, exemplo estendido com interpolação de strings aqui. Vamos copiar essa interpolação de string. Vamos voltar ao nosso botão, e aqui, vou usar essa interpolação de strings. Também preciso importar CSS chamado export de componentes estilizados. Agora, se voltarmos ao aplicativo, nada será alterado. Mas o que exatamente essa interpolação de strings faz? Em primeiro lugar, podemos usar a interpolação de strings aqui porque escrevemos CSS aqui dentro de crases. Dentro dos backticks, podemos interpolar o JavaScript usando os colchetes $ e curly. Aqui passamos uma função que retorna esse CSS, digamos, outra marcação CSS aqui. O que está acontecendo? Aqui usamos algo chamado argumento de adereços. Esse argumento será um objeto que tem a propriedade da chave primária, mas nada muda. Esses adereços aqui se referem aos adereços que realmente passamos para o componente. Se eu passar o primário aqui, será um suporte personalizado para esse componente de botão , o que significa que ele estará disponível aqui sob esse objeto props. Se eu voltar ao aplicativo, você verá como esses estilos mudaram. Se eu examinar a marcação, esses são os estilos que foram aplicados quando passamos o suporte principal. Eles sobrescrevem nossos estilos básicos. Para deixar isso mais claro, vamos criar outro botão chamado também hello, mas sem passar o atributo primário, sem passar o adereço primário. Você pode ver agora que eles são diferentes. Eles têm a mesma classe base aqui, gerada de forma exclusiva, mas a segunda classe é única. Dessa forma, podemos aplicar estilos dinâmicos usando componentes estilizados. Você pode basicamente passar qualquer adereço aqui. Pode ser qualquer coisa que não seja primária. Digamos que seja como tamanho da fonte e você possa especificar quantos pixels deseja, por exemplo, 20. Então, dentro da interpolação de strings, usando essa função, você pode retornar CSS com base nos adereços que você passa para o componente. Por exemplo, digamos que quiséssemos especificar o tamanho da fonte dinamicamente para cada botão, chamaríamos novamente outra interpolação de string dentro desse componente de estilo e aqui simplesmente passaríamos. No tamanho, se passarmos o tamanho da fonte, inclua CSS, que tem a propriedade de tamanho da fonte com propriedades de interpolação contraditória . Os pixels de tamanho da fonte que passamos. Basicamente, interpolamos JavaScript em marcação CSS. Agora, se voltarmos aqui e inspecionarmos o elemento, temos o tamanho da fonte aqui, 20 pixels. Acabei de notar que também temos esse atributo de tamanho de fonte anexado ao elemento do botão. Isso pode não ser necessário e talvez nem seja desejado. Acho que quando passamos algo aleatório para iniciar componentes e queremos disponibilizá-lo apenas como um argumento como parte desse objeto props aqui, queremos prefixá-lo com $ para permitir que os componentes estilizados entendam que, por favor, não digamos, interpolam. Não transmita esse tamanho de fonte como o atributo real do elemento subjacente. Torne-o disponível somente dentro dessa interpolação de strings quando aplicarmos estilos. Agora, nos referiríamos ao tamanho da fonte dos adereços aqui, ao tamanho da fonte dos adereços com o prefixo $, se eu não estiver errado. Sim, agora você pode ver que ainda temos os estilos e ainda funciona. Dessa forma, podemos aplicar estilos dinâmicos. Se voltarmos à documentação aqui, podemos encontrar outro exemplo de componentes estilizados. Criamos outro componente estilizado chamado container. Vamos seguir em frente e fazer isso no topo. Vou criar esse estilo de tempo, o div, o componente no final que teremos será o contêiner. Agora podemos colocar nossos botões no componente do contêiner. Se inspecionarmos, novamente, você verá um nome de classe exclusivo que identifica especificamente esse componente que tem os estilos correspondentes. Eu diria que esta é uma boa introdução para componentes de estilo. Você pode ver que é muito fácil estilizar o aplicativo usando essa abordagem porque tudo aqui é um componente. Pode ser, digamos, confuso diferenciar entre componentes regulares e componentes instalados, mas essas são as desvantagens. Você precisa encontrar a média dourada onde deseja ter seus estilos ou onde deseja ter seus componentes regulares. Mas os componentes de estilo são uma solução muito popular. Eu diria. Além disso, uma coisa que ele também fornece é algo chamado tema global ou configuração global. Se voltarmos aos documentos de componentes estilizados e, no canto superior direito, pesquisarmos o tema, podemos encontrar a referência do provedor de tema, e a referência do provedor de tema é algo que vamos tentar agora. Vamos importar o provedor de temas componentes estilizados aqui na parte superior. Em seguida, seguindo esse exemplo, passaremos o tema prop para o componente do provedor de tema. O tema que precisamos passar aqui deve ser um objeto. Vamos defini-lo em algum lugar no topo. Vamos chamá-lo de tema. Será apenas um objeto e esse objeto, o que você especificar aqui, ficará disponível dentro da interpolação de strings dentro de cada componente estilizado. O que significa que aqui, você pode definir qualquer configuração global que gostaria de usar em componentes estilizados. Pode ser em cores, pode ser, digamos, tamanhos de fonte, pode ser uma família de fontes, nas bilheterias. Quando vamos estilizar o aplicativo, usaremos cores e família de fontes, por exemplo, aqui podemos especificar cores. Digamos que o principal será apenas vermelho. Em seguida, passamos o objeto do tema pelo provedor do tema aqui. Agora, dentro da interpolação, onde quer que você queira usar esse conflito global de temas que você tem aqui, basta escrever que a cor será novamente reaberta a interpolação. Passamos uma função que deve retornar uma marcação CSS de string. Serão, digamos, adereços. Props.theme e o props.theme se referirão a esse objeto aqui. Props.theme.colors.main. Agora, se voltarmos ao aplicativo e vermos, cor ficará vermelha. Agora, em vez de escrever vermelho em todos os componentes estilizados, você apenas se referiria a props.theme.colors.main. Então, em vez de mudar essa cor em todos os lugares, você terá um único lugar onde essa cor é definida. Por exemplo, agora decidi mudar minha cor principal de vermelho para azul. Eu apenas digitaria azul aqui e isso se refletirá em todos os componentes aos quais prompts.theme colors main é referido. Vamos adotar essa abordagem para criar, digamos, alguma configuração global nas bilheterias. Agora, essa foi uma introdução aos componentes estilizados. Agora vamos comparar o que exatamente isso nos dá, quais são exatamente as desvantagens e qual é a diferença entre, digamos, usar componentes de células e uma forma tradicional de usar CSS. Vou abrir o Paint. À esquerda, teremos algo chamado CSS estático e, no canto direito, teremos algo chamado CSS em tempo de execução. Os componentes estilizados fazem parte do CSS em tempo de execução, mas vamos começar com a primeira estática. O que é CSS estático? Da maneira tradicional, quando escrevemos CSS, nós os escrevemos dentro de arquivos CSS e, em seguida, os arquivos CSS são importados para o aplicativo. Por exemplo, se dermos uma olhada no GitHub, eles usam CSS estático para estilizar seu site. O que quero dizer com isso é que, se olharmos dentro da marcação deles, dentro da hashtag , eles carregam arquivos CSS, e se abrirmos um desses estilos, um dos CSS, talvez vamos abrir outro. Existe um global. Tem esses nomes de classe, como borda de cor inversa, talvez algo como BG grey. Eles importam arquivos CSS estáticos que foram definidos no momento da criação e, em seguida, usam os nomes das classes que vêm desses arquivos CSS dentro da marcação. Vamos abrir a etiqueta corporal. Aqui você vê nomes de classes regulares, compreensíveis e abrangentes. Mas se olharmos para dentro dos componentes estilizados, é um pouco diferente. Nomes de classes estáticas, independentemente do que esteja definido no momento da construção. Se quisermos aplicar nomes de classes dinâmicas ou se quisermos aplicar estilos dinâmicos com nomes de classes CSS estáticos, abordagem com CSS estático. Digamos que temos um botão aqui que pode ser primário, criaríamos, digamos, com uma classe de botão de pontos CSS normal, depois criaríamos uma classe primária de pontos e, quando vamos estilizar esse botão, vamos apenas alternar os nomes das classes. Por padrão, digamos que fosse um elemento de botão que você teria aqui, como ponto, digamos classe de botão aqui, e quando você clica em algo, esse botão tem um nome de classe adicional chamado primário. Dessa forma, você pode usar nomes de classe estáticos estilos CSS estáticos para criar nomes de classes dinâmicas especificamente para elementos. Com componentes estilizados ou com CSS em tempo de execução, é diferente. O CSS é, digamos, construído com precisão. O que quero dizer com isso. Se olharmos dentro do nosso aplicativo aqui, na hashtag, não temos nenhum arquivo CSS conectado. A questão é de onde exatamente esses estilos vêm? Eles estão vindo de. Deixe-me ver. Se abrirmos o chapéu. Aqui temos a etiqueta de estilo. O problema é o CSS em tempo de execução, o que ele faz, os componentes com estilo de biblioteca injetam estilos dinamicamente na página usando a tag de estilo. Se abrirmos componentes estilizados , marcações e documentação oficial, eles os terão, deixe-me ver, eles têm exatamente a mesma tag de estilo aqui em que eles têm exatamente a mesma tag de estilo esses estilos são injetados. Isso está vazio, não sei por quê. Vamos ver isso, isso é uma confusão global. Esses não são estilos dinâmicos. Todos esses estilos que você vê aqui são injetados na etiqueta de estilo. Está vazio aqui. Deixe-me tentar com o código-fonte da página. Aqui não está vazio. Todos esses estilos aqui são injetados aqui dentro da tecnologia de estilo. O fato é que esses arquivos são injetados no Defly. Eles não foram definidos no momento da construção. O que significa que quando eu acesso esta página, primeiro, a tag de estilo estava vazia. Mas quando eu realmente vou para aquela página, os componentes estilizados, as partes, qualquer JavaScript que estavam aqui dentro de crases. Em seguida, leva algum tempo para processar isso, analisar o que escrevemos aqui, então ele cria essa marcação CSS e depois injeta essa marcação CSS aqui dentro da tag de estilo. Dessa forma, os estilos são injetados em tempo de execução, durante as interações do usuário. O problema com essa abordagem é que, quando você alterna entre as páginas, ela injeta apenas os estilos necessários para exibir o conteúdo nessa página específica. Isso significa que ele carrega estilos necessários apenas para o conteúdo atual. Ele nunca injetará estilos que não sejam exigidos por essa página específica. Ao contrário dos aplicativos tradicionais aqui, você importa esse arquivo CSS grande, ele tem muitos nomes de classes diferentes, mas eles podem não ser usados na página. Os componentes estilizados, em primeiro lugar, injetam estilos dinamicamente em tempo de execução e, se digamos que algo seja dinâmico, por exemplo, alteramos a sonda aqui, esses estilos também serão injetados dinamicamente adicionados às tags de estilo para que fiquem disponíveis na página. Com aplicativos tradicionais, isso não está certo. Tudo precisa ser predefinido antecipadamente e carregado por meio de arquivos CSS. O problema com essa solução CSS NGS, especificamente com JavaScript em tempo de execução, é que ela leva tempo. Leva tempo para analisar esse JavaScript para traduzi-lo em CSS e injetá-lo na página. É computação, leva tempo. Isso significa que se você tiver uma árvore de elementos muito grande, digamos, na página que é um componente estilizado, ela pode se tornar um gargalo em algum momento, porque o JavaScript leva tempo para processá-la. Se você tiver milhões de centenas de componentes na página , pode levar um segundo, alguns segundos, enquanto os estilos serão injetados na página. Mas na maioria dos aplicativos, esse não é o caso. Mas você realmente deve considerar essa opção se trabalha em aplicativos maiores e é você quem toma decisões. Mas, novamente, na maioria das vezes, não estou aqui para te assustar. Na maioria das vezes, isso é totalmente normal e os usuários finais nem perceberão a diferença. Para bilheteria, vamos usar componentes estilizados. Vamos experimentar essa opção. As vantagens dos componentes estilizados são que eles facilmente nos permitem definir primeiro a configuração global com JavaScript. Criamos o objeto do tema e ele fornece tudo por meio da interpolação dentro dos componentes estilizados. A segunda vantagem é que podemos aplicar facilmente nomes de classes dinâmicas usando, novamente, a mesma interpolação de strings e, terceiro, tudo é JavaScript. Você não precisa criar arquivos CSS de forma alguma. Tudo está escrito aqui diretamente. A desvantagem é que, em primeiro lugar porque se trata de JavaScript, leva tempo de computação. Novamente, em aplicativos muito grandes, isso pode ser um gargalo. Em aplicativos menores, isso nem será visível. Segunda desvantagem, pode ser confuso porque agora tudo é um componente e é fácil confundir componentes regulares e componentes estilizados. Acho que é isso. Por enquanto, vamos remover todas as mudanças que fizemos dentro do GS6 doméstico. Vou manter a instalação de componentes estilizados e , no próximo vídeo, finalmente estilizaremos o aplicativo inteiro usando componentes estilizados. vejo lá. 85. 29 Estilando o aplicativo p1: Oi, lá. Neste vídeo, continuaremos falando sobre estilos. Neste vídeo, vamos estilizar nosso aplicativo, não inteiramente, mas vamos fazer a parte principal. Vamos embora. No vídeo anterior, eu já instalei styled-components, acabei de executar npm install styled-components, posso executar esse comando novamente para garantir que o pacote esteja definitivamente instalado. Logo depois disso, vou iniciar o servidor de desenvolvimento local e vamos ver exatamente onde vamos começar a estilizar nosso aplicativo. Os estilos que vou usar neste vídeo serão compartilhados com você por meio do convidado ao qual você já tem acesso. Vamos começar por aqui. Em primeiro lugar, vamos conectar a fonte do Google, especificamente o Roboto, ao nosso aplicativo e talvez alterar o título. Porque agora é apenas um aplicativo React. Vou simplesmente ir aqui, StylingPart1.md e copiar o índice HTML que tenho aqui. Em seguida, vou navegar até index.HTML. Aqui, em vez do título, conectarei essa fonte, carregarei essa folha de estilo e alterarei o título para Box Office. Agora, ele aparecerá em Box Office. Meu aplicativo aparece na bilheteria e eu tenho essa fonte Roboto conectada aqui. Incrível. Agora, do vídeo anterior, você lembra que eu falei sobre o tema de componentes estilizados, usamos o provedor de temas. Vamos seguir em frente e criar esse tema. Se eu voltar para o convidado, tenho esse objeto aqui. Esse objeto aqui será nossa configuração global de tema. Apenas algumas cores mais a fonte global que vamos usar, o Roboto que acabamos de conectar dentro do índice HTML. Vou pegar esse objeto de tema, vou até, deixe-me ver, o aplicativo JS6. Aqui, vou adicionar esse objeto de tema e agora preciso usar o provedor de tema e passar esse objeto de tema para os componentes subjacentes. Em primeiro lugar, vamos nos livrar dessa marcação aqui, não precisamos mais dela, ela foi comentada. Então, a partir dos componentes estilizados, vou importar o provedor de temas. Aqui abaixo, consulte o provedor do cliente, ou ainda por cima. Realmente não importa, vou chamar o provedor de temas, vou encapsular o roteador do meu navegador no provedor de temas e, como objeto de tema, vou passar o objeto de tema que temos aqui e o copiamos do convidado. Agora, você pode ver que realmente foi essa nova edição, digamos que com esse novo objeto de tema, nosso aplicativo j6 ficou um pouco poluído. O que podemos fazer nesse caso é talvez oscilar parcialmente ou extrair lógica que escrevemos até agora aqui em um arquivo separado. Por exemplo, podemos de alguma forma extrair esse provedor de tema e o objeto do tema em um arquivo separado e gerenciar tudo a partir daí. O que quero dizer com isso é que, dentro da pasta de origem, podemos criar um novo arquivo chamado theme.jsx. Agora, aqui podemos mover o objeto do tema, e aqui podemos criar nosso próprio componente, que talvez seja chamado de tema global. Vamos tentar criar esse, const, GlobalTheme. Vamos usar este GlobalTheme dentro do appjsx em vez do provedor de temas. Não precisaremos importar o provedor de temas de componentes estilizados, gerenciar o objeto do tema aqui dentro e, em seguida, usar o provedor de tema para passar o objeto de equipe, podemos extrair toda essa lógica dentro do tema jsx, gerenciar tudo a partir daqui. Para isso, podemos criar apenas um componente chamado tema global e não podemos agrupar o roteador do navegador no componente de tema global, assim mesmo. Que vamos importar do considerado jsx. Deixe-me fazer isso. Vou apenas importar do tema global. Esse GlobalTheme precisa ser exportado para, vou chamar export const, GlobalTheme. Agora parece muito mais limpo. Este GlobalTheme deve entregar todos os seus filhos que são passados para dentro. Isso significa que dentro do componente GlobalTheme, vou desestruturar o adereço infantil e, a partir desse componente, vou devolver o provedor de tema, que é importado de componentes estilizados, e crianças mais velhas entrarão. Para o adereço do tema, passarei o objeto do tema aqui. Agora, criamos o tema, gerenciamos a lógica no tema jsx, no entanto, também precisamos aplicar alguns estilos globais. No momento, temos alguns estilos globais definidos aqui dentro do índice CSS, mas para nossa solução de estilo, usamos componentes estilizados. Na verdade, podemos usar componentes estilizados para criar um tema global, o que, digamos, não é, de alguma forma o escopo de algum componente específico. Portanto, alguns estilos são definidos por componentes estilizados que estão disponíveis globalmente. Em vez de usar CSS de índice, podemos realmente excluir esse arquivo. Dentro do índice jsx, agora podemos remover a referência a um índice CSS existente. Agora, precisamos de alguma forma criar estilos globais. No componente estilizado, temos uma coisa chamada criar estilo global. Podemos procurar isso na documentação. Deixe-me ver. Crie um estilo global, referência APA, crie um estilo global, somente na web. É apenas uma função que você chama. Novamente, você escreve estilos globais, CSS global e depois o usa apenas como um componente. Basicamente, o mesmo que o uso regular de componentes de estilo, mas desta vez não será direcionado a componentes específicos. Os estilos serão aplicados globalmente. Vamos chamar de criar estilos globais aqui, mas temos aquele convidado interno que é compartilhado conosco. Então, podemos simplesmente partir daqui, vamos copiar e colar. Eu apenas chamo de criar um estilo global que foi importado de componentes estilizados e, em seguida, especifico alguns estilos globais, especificamente aqui para o orçamento. Aqui, o que eu faço, eu uso a interpolação de strings para interpolar esse objeto de tema e pegar família de fontes que está definida aqui. Você se lembra que, como usamos backtest aqui, podemos usar interpolação de strings, devemos passar uma função que retorne algum CSS que será interpolado diretamente aqui. No vídeo anterior, usei adereços, logo em seguida fiz props.theme. Mas como o primeiro argumento é um objeto que contém a chave do tema, podemos desestruturar a chave do tema diretamente nos argumentos. Isso é totalmente opcional. Isso é apenas para, digamos, simplificar e encurtar essa sintaxe. Vou apenas desestruturar o tema a partir daqui e usar a família de fontes do tema. Novamente, o objeto do tema se refere a isso, o objeto que definimos aqui e depois o passamos para o provedor do tema. É por isso que está disponível dentro de nossa definição de componentes estilizados. Em seguida, usamos esses estilos globais dentro de nossa marcação, como um componente irregular. Agora, tudo isso se torna disponível magicamente. Se acessarmos nosso aplicativo novamente e procurarmos a etiqueta corporal, deixe-me encontrá-la, você poderá ver que os estilos foram aplicados. Temos a família de fontes, Roboto sans-serif, assim como definimos no tema e no resto do CSS que colocamos aqui. Ótimo. Agora, qual será nosso próximo passo? Acho que vamos começar com a navegação primeiro porque temos uma pequena coisa que precisamos discutir. O que quero dizer com essa pequena coisa, quando navegamos entre as páginas, queremos indicar qual página está ativa no momento. Por exemplo, se eu estiver na página inicial, gostaria de mostrar ao usuário que esse link está ativo. Se eu navegar até o início, quero indicar que o link inicial está ativo no momento. Como posso fazer isso? Se voltarmos aos componentes, nav.sjsx aqui temos essa marcação simples, apenas mapeamos nossa matriz de links para o elemento LI com o componente de link que é importado do react-router-dom. Como podemos verificar de alguma forma se esse link que renderizamos aqui está ativo. Mas esse roteador React tem um componente específico e, se consultarmos a documentação e se você procurar NavLink nos componentes, podemos ler na descrição que um NavLink é um tipo especial de link que sabe se está ativo ou não. Se lermos mais, ele diz que, por padrão, uma classe ativa é adicionada a um componente NavLink quando está ativo; portanto, em vez de usar link, podemos usar um componente chamado NavLink e, quando ele estiver ativo , a classe ativa será anexada a esse link por padrão. Vamos tentar ver. Substituí o link pelo navlink do React-Router-DOM, volto ao meu aplicativo e inspeciono a marcação. Eu vejo a tag [inaudível] aqui, e você pode ver que agora estou na página inicial e vejo que plus active foi adicionado a esse link. Se eu navegar para casa, agora o plus active está sendo anexado à casa. Assim, o roteador React nos deu a capacidade de estilizar nosso link ativo apenas substituindo link por navlink. simples quanto isso. Você pode ler mais sobre como esse NavLink pode ser personalizável, talvez com base em algumas condições, mas no nosso caso, ele deseja ser alterado de alguma forma, a interface, por exemplo, se olharmos a documentação, podemos usar essa tag de estilo, que pode ser uma função que recebe essa chave ativa do primeiro argumento. Não vamos mais longe com isso, vamos voltar para nosso convidado aqui e eu já preparei os estilos para nós. Deixe-me explicar o que temos aqui. Em primeiro lugar, vamos copiar esse componente com estilo de lista de navegação e colocá-lo em algum lugar na parte inferior. Antes de tudo, precisamos importar o estilo. Na parte superior, chamaremos o estilo de importação de componentes estilizados. Aqui, criamos um elemento UL simples, este com estilos. Agora vamos substituir a UL, por romancista, e tudo dentro da marcação interna será estilizado. Novamente, criamos estilos, pontilhamos um elemento de lista ordenada com estilos e , em seguida, também especificamos que cada elemento LI interno terá uma margem de 10 pixels. Vamos experimentar e ver. Voltamos ao aplicativo, você pode ver que o layout foi alterado. Se olharmos para a classe L, assim como antes, temos uma classe gerada de forma exclusiva especificamente para esse elemento da lista Nav, especificamente para esse elemento UL, podemos ver os estilos. Se inspecionarmos o elemento LI, ele também tem estilos. Ótimo, funcionou. Mas agora, o que dizer dos links? Porque não tocamos em nenhum componente do NavLink. Se voltarmos aqui para o convidado, também temos o link estilizado aqui. Deixe-me copiá-lo e eu explicarei o que temos. Os componentes estilizados são, digamos, versáteis o suficiente para nos permitir não estilizar elementos HTML básicos, digamos nativos. Isso também nos permite estilizar outros componentes. Aqui estou chamando styled como uma função e passo o componente NavLink interno como argumento. Dessa forma, estendemos componente NavLink com esses estilos que temos aqui. Dessa forma, no final, esse estilo de link será apenas um componente NavLink, mas com essa folha de estilo CSS, tão simples quanto isso. Agora, em vez de usar o NavLink aqui, posso usar com segurança o estilo Link ou talvez possamos até chamá-lo de estilo NavLink, se você quiser, vamos mantê-lo no estilo de link. O que fazemos lá dentro apenas especificar novamente a cor do objeto do tema e aqui temos o e comercial, e então temos.active, o que significa quando esse elemento, então esse e comercial se refere a si mesmo, que significa que o e comercial aqui se refere ao próprio componente NavLink, e então quando esse componente, quando esse elemento, quando esse NavLink tem a classe ativa, especificamos que ela terá colorido essa e depois a outra marcação para obter o efeito que desejamos. Vamos tentar ver. O que nós temos? Voltamos aqui e você vê que agora temos essa linda navegação. Quando navegamos, agora é indicada a página que está ativa no momento. Ótimo, vamos seguir em frente. Se voltarmos para o convidado aqui, teremos mais um momento aqui chamado Rádio personalizada. Para esses botões de rádio que temos aqui, digamos que vamos criar botões de rádio personalizados. Quando se trata de entradas de estilo como caixas de seleção ou rádios personalizados, é um pouco complicado, mas nada realmente complicado. Se formos para o componente do formulário de pesquisa que temos aqui, veremos que temos dois rótulos. Dentro de cada etiqueta, temos uma entrada do tipo rádio. Se precisarmos criar um elemento de rádio personalizado que queiramos ter um estilo completo, precisamos adotar uma abordagem um pouco diferente dessa para torná-lo, digamos, reutilizável. O que quero dizer com isso é que sugiro que criemos um componente que chamaremos de rádio personalizado. Em componentes, vou criar um novo arquivo chamado Custom radio.jsx, então aqui vou criar um rádio personalizado. Aqui, por enquanto, será apenas um rótulo. Vou colocá-lo de lado e vamos ver o que temos. Temos rótulo, e dentro temos texto e, em seguida, temos entrada. Então, podemos simplesmente copiar essa marcação aqui e colocá-la em um rádio personalizado. Agora, o que queremos fazer e qual interface queremos oferecer a esse elemento de rádio personalizado? Vamos avaliar exatamente como gostaríamos de usá-lo. Então, agora, criamos um rótulo e, em vez disso, passamos a entrada para dentro. partir de agora, será um componente chamado rádio personalizado. Vamos chamar rádio personalizado, e para esse rádio personalizado, idealmente, gostaríamos de passar todos os adereços, todos os atributos que passamos para o elemento de entrada do tipo rádio. Então, vou copiar tudo isso, talvez sem rádio tipo, porque esse componente já é sobre rádio. Vamos passar o nome e a verificação de valor inalterados. Mas e quanto ao rótulo? Quais são nossas opções? primeira opção é que talvez possamos passar esse rótulo quando crianças, por exemplo, assim. Isso pode ser uma opção, mas, em vez disso, eu pessoalmente prefiro passá-la como um atributo. Então, vamos dizer que defina mais um atributo, mais um adereço, que chamaremos rótulo e vamos passar os shows aqui. Em vez de usar crianças, será um componente de fechamento automático com mais um suporte adicional chamado rótulo. Agora, como podemos lidar com tudo isso dentro de um rádio personalizado? Em primeiro lugar, vamos especificar adereços aqui e, a partir dos adereços, vamos desestruturar. Primeiro, vamos pegar esse atributo de rótulo, adereços rotulados que vamos passar, depois dentro da marcação, vamos interpolar esse rótulo, e agora nosso objetivo é pegar todos esses adereços, o resto dos adereços que passamos, não importa quais sejam esses adereços, sabemos que todos eles serão de alguma forma redirecionados para o elemento de entrada aqui. Então, a questão é: como podemos fazer isso? Não vamos desestruturar todos os adereços um por um, é? Não queremos fazer isso. Sabemos que pegamos o rótulo e o resto definitivamente vai para o elemento de entrada. No React, como o objeto props ainda é apenas um objeto JavaScript, as mesmas regras se aplicam. Podemos usar essa estruturação, podemos usar o operador de propagação, podemos usar o operador resto. Então, todas essas regras se aplicam. O que eu sugiro é que podemos realmente usar o operador de propagação. Podemos chamar três pontos aqui e especificar adereços de entrada. Usando essa sintaxe aqui, talvez eu possa embuti-la diretamente aqui. Então, pegamos apenas o suporte do rótulo aqui e, o que quer que passemos, o resto dos adereços estará disponível no objeto de adereços de entrada. Agora podemos pegar esse objeto de adereços de entrada e espalhar todos esses adereços que passamos usando o operador spread desse jeito. Em primeiro lugar, usamos o operador rest para, digamos, acumular todos os adereços que passamos para o rádio personalizado, todos eles ficarão disponíveis em adereços de entrada, objeto e, em seguida, espalhamos todos os adereços, todas as teclas dentro dos adereços de entrada, como adereços, como atributos do elemento de entrada. Agora, a partir do rádio personalizado, vamos exportar por padrão o rádio personalizado, e agora precisamos de alguma forma estilizar tudo isso. Então, se voltarmos para o convidado aqui, temos um rádio estilizado. Vamos copiar tudo isso e depois colocá-lo na parte inferior. Agora, primeiro precisamos importar componentes estilizados a partir de componentes estilizados. Aqui, criamos uma etiqueta de ponto estilizada e chamo o componente de retorno de rádio estilizado. Em vez de rótulo, podemos usar apenas um rádio estilizado e agora tudo funcionará magicamente. Então, toda essa marcação CSS é apenas para criar um botão de rádio personalizado completamente estilizado com o tema que temos e as cores que definimos dentro desse tema. Agora, vamos salvá-lo. Além disso, precisamos adicionar uma marcação adicional aqui, apenas um elemento de extensão vazio. Simples assim. Ele será usado dentro da marcação, será estilizado. Agora, vamos voltar e dentro do formulário de pesquisa, vamos usar esse rádio personalizado. Agora, em vez de usar um rótulo e assim, vamos importar primeiro um rádio personalizado. Importe componentes de ROM de rádio personalizados do rádio personalizado, assim mesmo, e o rádio personalizado é exportado por padrão, então eu não preciso usar exportação nomeada, importação de nome. Isso está errado. Agora, vou usar um rádio personalizado, passarei o suporte rotulado e o resto dos adereços serão redirecionados, digamos, para o elemento de entrada subjacente. Então, a mesma coisa que farei com os atores. Eu não preciso mais desse rótulo aqui. Vou copiar essa etiqueta de rádio personalizada para atores e os adereços serão o resto. Mais uma coisa que notei aqui, especificamos que essa entrada será do tipo rádio. No entanto, não especificamos em nenhum lugar que nossa entrada subjacente também tenha o tipo rádio. Primeiro, digamos todos esses adereços que passamos para rádio personalizado redirecionam para o elemento de entrada subjacente, mas o que quer que passemos, podemos substituí-los pelos adereços que definimos aqui, digamos, incluindo-os depois de fazermos a propagação. Portanto, nossa entrada será do tipo rádio. Quando especificamos adereços após fazermos esse spread, tudo o que especificarmos será substituído por isso. Por exemplo, se aqui para um rádio personalizado, eu vou passar o tipo, digamos texto, isso será substituído por tudo o que eu especificar após esse spread. Mas se eu especificar aqui dentro de um rádio personalizado, digitar rádio antes da propagação, o spread substituirá, digamos, os adereços padrão que eu passo aqui. Mas se for definido posteriormente, será sobrescrito. Exatamente as mesmas regras que você aplicaria se espalham dentro de um objeto simples. Então você espalha algo aqui, digamos, adereços de entrada, e então você especifica isso. O tipo será rádio. Basicamente, tudo o que temos na linha 12 é traduzido aproximadamente. O que você vê dentro dessas linhas três a seis, aproximadamente o mesmo. Nós especificamos o tipo de rádio, não precisamos especificar o tipo de texto aqui. Agora podemos salvar tudo. Podemos voltar ao nosso aplicativo e vemos que agora temos elementos estilizados, mas esquecemos de excluir o rótulo aqui e agora você pode ver que funciona. Se eu especificar, procure meninos, agora, na verdade, procura atores. Então eu mudei para os programas e funciona. Então está tudo bem aqui, e acho que será isso especificamente para este vídeo. Nós abordamos, digamos, as coisas essenciais para o estilo. Acho que conseguimos fazer muita coisa. Por enquanto, vamos nos limitar a isso e comprometer tudo. Vamos dar uma visão geral rápida do que fizemos. Em primeiro lugar, dentro do index.HTML, adicionamos esse link à fonte Roberta, definimos o título como Box office, dentro do app.jsx, usamos o componente de tema global que criamos dentro do jsx. Então, criamos esse componente global que é apenas um invólucro sobre o provedor de temas e estilos globais a partir de componentes estilizados. A lógica é gerenciada dentro do tema jsx. Criamos esse objeto de tema global que usamos nossos componentes estilizados em todo o aplicativo. Então, dentro do navs.jsx, usamos o componente nav link porque esse não é um componente que nos fornece o link ativo. Assim, o link ativo recebe a classe ativa e, em seguida, usamos essa classe ativa dentro da nossa marcação CSS para estilizar o link ativo. Em seguida, criamos e usamos o componente de rádio personalizado, que é um botão de rádio personalizado que criamos novamente, com a ajuda de componentes de estilo. Também conhecemos esse novo pequeno truque aqui quando precisamos redirecionar, digamos, ou passar os adereços para o elemento subjacente usando os operadores rest e spread. Portanto, podemos realmente espalhar um objeto em um elemento e, quaisquer que sejam os valores-chave que ele tenha, todos eles serão considerados como adereços, como atributos do elemento. Isso soou muito. Vamos confirmar tudo e, digamos , instalar componentes estilizados, então diremos que isso criou um feixe global com o SC. Vamos simplificar com componentes estilizados. Criou um rádio personalizado. Usou o link de navegação do roteador React para estilizar o link ativo. Parece incrível. Vamos enviar tudo para o GitHub e, no próximo vídeo, continuaremos com os estilos. Te vejo lá. 86. 30 Estilando o aplicativo p2: Olá novamente. No último vídeo, começamos a estilizar o aplicativo usando componentes estilizados. Neste vídeo, continuaremos. Se voltarmos ao convidado compartilhado com você, você poderá encontrar stylingpart2.empty. Esse é o arquivo ao qual podemos nos referir. Temos muitas marcações CSS, e escrever tudo isso vai ser muito longo e entediante. Para evitar isso, vamos usar apenas a folha de estilo existente, que você e eu não precisemos escrever tudo isso sozinhos. Vamos um por um. O que temos dentro de StylingPart2.md. Primeiro, temos o AppTittle.jsx e temos componente no estilo Titlewrapper aqui. Vamos copiá-lo. Vamos voltar ao nosso aplicativo. Vamos para onde está? Qual era o arquivo? AppTittle.jsx? Vamos para AppTittle.jsx e, aqui na parte inferior, usaremos esse titlewrapper e importaremos componentes estilizados a partir de componentes estilizados. Agora, em vez do div aqui, vamos usar o Titlewrapper, e todo esse texto h1 e p interno será estilizado de acordo com nossos estilos dentro do styled div aqui. Vamos salvá-lo. Vamos voltar ao aplicativo e ver. Agora, boom, temos esse título bem centrado. Incrível. Vamos continuar. Em seguida, temos o formulário de pesquisa na lista. Vamos copiar tudo isso e navegar para pesquisar. No último vídeo aqui, já criamos esse componente CustomRadio. Agora vamos adicionar estilos adicionais, para que todo o nosso formulário tenha uma boa aparência. Vou colocar todos esses componentes estilizados na parte inferior. No entanto, só para mencionar, você pode colocar esses componentes estilizados em qualquer lugar. Você pode criar searchform.style.jsx e colocar todos os componentes estilizados lá e importá-los dentro do formulário de pesquisa. Isso ocorre caso você não queira poluir o próprio arquivo do formulário de pesquisa. Por causa dos componentes estilizados, CSS, ele ocupa muito espaço. Caso você não queira escrever tudo isso aqui, você pode escrevê-lo em um arquivo separado e importá-lo aqui no site. No nosso caso, escreveremos tudo na parte inferior. Primeiro, precisamos importar o estilo, pressiono a inteligência para abrir o menu suspenso. Aqui, importo componentes estilizados a partir de componentes estilizados, como sempre. Agora, vamos usar esses componentes. Primeiro, temos um elemento de entrada estilizado. Temos essa entrada do tipo texto, então, em vez de usar entrada, vamos usar o componente de entrada de pesquisa, componente de estilo que criamos. Em seguida, temos essa div no estilo RadiosWrapper. Esta será uma div adicional aqui, estilizada ou como eu a chamei? Era RadiosWrapper. Será apenas um div que envolverá nossos dois rádios personalizados desse jeito. No final, também temos o invólucro do botão de pesquisa, que será outro invólucro div adicional para esse elemento de botão. Podemos usar o wrapper do botão de pesquisa e colocaremos o botão do tipo enviar dentro. Isso é o que escrevemos dentro dos estilos. Vamos salvá-lo. Vamos voltar ao formulário e agora basta dar uma olhada nisso. Parece muito bom até agora. Vamos tentar procurar meninos. Você pode ver que nosso cartão ainda não está estilizado. Vamos corrigir isso no momento. Mas o formulário parece ótimo. A propósito, não temos nenhum espaço reservado aqui dentro desta caixa de pesquisa. Talvez vamos adicioná-lo. Vou passar o prompt de espaço reservado para pesquisar o componente de entrada, que na verdade não é como um componente. Ainda é o elemento de entrada. O espaço reservado será procurar por algo. Vamos tentar ver. Agora, parece melhor. Ótimo. Vamos mais longe. Além disso, temos um conjunto de arquivos que são prefixados com common. Esses são componentes estilizados que serão compartilhados entre vários arquivos dentro do nosso aplicativo. Eles serão importados para vários outros componentes. É por isso que eles são prefixados com comum. Isso significa que dentro dos componentes, provavelmente criaremos uma pasta chamada common e colocaremos esses componentes estilizados lá. Primeiro, temos flexgrid.jsx. Vamos copiar isso. Vamos criar um novo arquivo aqui chamado flex grid. Dentro desse arquivo, apenas exportamos o componente flexgrid. Nada especial. Então temos o cartão de pesquisa. Este será um conjunto de componentes que usaremos para estilizar o cartão de pesquisa. Tanto para shows quanto para atores, copiamos essa marcação. Vamos colocá-lo aqui. A partir daqui, exportamos duas coisas pesquisar o invólucro da imagem e depois pesquisar os componentes do cartão. Usaremos esses dois para estilizar os cartões de pesquisa. Agora vamos mais longe. Aqui temos StarIcon jsx. Vamos criar este, StarIcon, jsx. Isso vai ser interessante. Este é apenas um div estilizado. No entanto, aqui vamos usar um adereço chamado ativo. Vamos passar um suporte ativo para mudar a cor desse StarIcon. Vamos abordar isso em um momento em que voltarmos a esse componente, quando vamos usá-lo. Agora temos mais uma coisa aqui chamada centro de texto. Nada de especial aqui. Apenas um div que centralizará o texto em seu interior. A próxima coisa que temos é chamada Pages Show.jsx. Vamos copiar tudo isso. Vamos para Pages Show.jsx. Assim como antes, vamos usar todos os nossos componentes de estilo. Na parte inferior, vamos importar componentes estilizados a partir de componentes estilizados. Vamos ver como podemos usar esses componentes. Embalagem de volta para casa. É denominado div e, por dentro, estiliza a tag âncora. Aqui temos o link que nos leva à página inicial. Vamos embrulhar isso no componente de embalagem doméstica. Eventualmente, parece algo assim. Em seguida, temos show page wrapper, que será o invólucro de toda a marcação aqui. Eu só vou usá-lo assim. Booms. Mostra o invólucro da página e a tag de fechamento mostra o invólucro da página. Então, também temos o InfoBlock, InfoBlock é esse div reutilizável para nossas informações adicionais para o programa. Aqui estarão os detalhes do InfoBlock, temporadas do InfoBlock e o elenco do InfoBlock. Aqui também temos isso. Ocorreu um erro, os dados estão sendo carregados. Em vez de apenas usar div, podemos reutilizar esse componente com estilo de centro de texto que criamos dentro da pasta atual. Vou importar de componentes, do centro de texto comum, e vou importar o centro de texto e, em vez de usar esses divs aqui, aplicarei o centro de texto. Incrível. Agora vamos tentar ver se eu clico em algum dos programas em ler mais. É assim que nossa página está agora. No entanto, ainda temos dados principais do programa sem estilo, ainda temos detalhes, temporadas e elenco sem estilo. Se voltarmos a ser convidados aqui, teremos elenco de programas, detalhes dos programas, temporadas e cartão de exibição. Vamos estilizar tudo isso agora. Vamos começar com o elenco. Vou copiar tudo isso e colocá-lo no elenco dos programas. No. Na parte inferior, o estilo será importado dos componentes estilizados e lista de moldes será o invólucro do molde. Dentro, temos coisas que serão denominadas como uma lista de nomes de classes. Na verdade, podemos usar esses nomes de classe em nossa marcação e eles serão estilizados porque é isso que especificamos para o div, os estilos. Dentro da lista de elenco, temos esta div, que será do nome da classe item cast. Então temos o invólucro de foto, que será nosso invólucro de imagem, na verdade, eu o chamo assim, e então temos ator, que será esse nome de classe ator. Incrível. Agora, se voltarmos aqui, não temos nenhum elenco disponível para este programa. Vamos tentar outra coisa. Temos uma imagem muito grande. Saiba o que está aqui. Vamos lidar com isso em um momento, mas você pode ver que agora, nosso elenco está estilizado. Parece muito legal. Agora, vamos mais longe. Vamos ver o componente de detalhes aqui. Os detalhes serão mostrados neste DetailsWrapper. Nada realmente especial aqui dentro do componente de detalhes, em vez de div, podemos simplesmente aplicar detailsWrapper. Vamos voltar e ver os detalhes. Nada realmente especial, apenas uma margem adicional aqui. Vamos voltar aos divs. Agora, temos temporadas aqui. Vamos copiar tudo isso. Vamos às temporadas. Na parte inferior, vou importar novamente o estilo de componentes estilizados. Temos o SeasonsWrapper. Isso é denominado div, SeasonsWrapper. Vamos usá-lo assim. Então, lá dentro, o que temos? Por que não foi usado? Porque eu esqueci o S. Também temos a SeasonList aqui. Vamos usar isso para aquela div quando mapeamos a marcação. Aqui dentro, também estilizamos itens sazonais. Em seguida, passamos na classe esquerda, depois na classe direita. Nosso item da temporada será essa div que mapeamos. O sobrenome será o item da temporada, conforme definido no componente do arquivo. Item de temporada. Então saímos da aula e da aula de redação. Mas aqui, temos a marcação a seguir, o que significa que queremos exibir temporadas e episódios. Vamos ver no lado esquerdo e o resto no lado direito. Podemos encerrar temporadas e episódios em div. Direto no div, podemos dar o nome da classe left. Então, para o div, daremos o nome da classe à direita. de estreia e a data de término desta temporada talvez possamos colocá-las dentro da etiqueta forte para torná-la ousada. Vamos tentar ver o que temos no final. Agora, temos isso, vamos ver. lado esquerdo e o lado direito são exatamente como definimos aqui. Não vemos nada de ousado aqui, mas agora vemos porque o temos. Vamos inspecionar a marcação. Ótimo. Nossas datas agora estão negrito porque estão dentro da etiqueta forte. Perfeito. Agora, vamos seguir em frente. Também temos o ShowCard aqui. Isso vai ser interessante finalmente. Dentro do ShowCard na parte inferior, vou colocar esta seção de ação e a seção StarBtn. Deixe-me importar o estilo dos componentes estilizados, como de costume. A primeira coisa que eu gostaria de fazer aqui é a seguinte. Se voltarmos ao nosso aplicativo e olharmos o resumo que retiramos aqui, como você se lembra, receberemos HTML bruto. Substituímos todas as tags HTML, caracteres HTML. Mas parece que está sendo cortado sem motivo. No final, podemos adicionar apenas três pontos para torná-lo mais fácil de usar, digamos. Podemos aplicar um modelo de string como este e, no final, podemos adicionar três pontos. Mas para torná-lo, digamos menos detalhado, podemos simplesmente concatená-lo usando o operador plus e ele nos dará exatamente o mesmo resultado, mas acho que parece muito melhor. É mais adequado neste caso. Se olharmos, agora, vemos três pontos no final, o que é incrível. Agora, vamos usar os componentes estilizados que temos aqui. Em primeiro lugar, não temos nenhum componente, digamos, estilizado que envolva nosso marcador, que forneça, digamos, estilos para o cartão, apenas para algo específico, como seção de ação e StarBtn. Mas criamos esse arquivo de componente de estilo comum chamado SearchCard.jsx e, por dentro, temos o cartão de pesquisa e o invólucro de imagem de pesquisa. Vamos usar esses dois dentro do ShowCard e usaremos esses dois cartões internos de ator mais tarde. Vou importar do SearchCard comum interno. Vou especificar que eu importe SearchCard e importe o SearchImageWrapper. Agora, o SearchCard será a div de embalagem. Então, o div que quebra a imagem será, na verdade, SearchImageWrapper. Esta ActionSection aqui será a div que define nossa seção de ações Leia mais nos botões StartMe. Então, também temos StarBtn aqui, que é um elemento de botão estilizado, que é isso. Agora, vamos tentar usá-lo. Vamos ver como nossos cartões estão agora. Você pode ver que eles não parecem ruins. Tudo parece válido, mas não temos, digamos, nenhum ícone aqui. O ícone que criamos anteriormente é esse StarIcon. Este é apenas um div estilizado com esse atributo CSS específico, digamos, clip-path. Vamos tentar usá-lo e ver como vai ficar. Em vez de usar os textos IsStarred Unstar me e Star me. Eu vou comentar isso. Lá dentro, passarei o componente StarIcon, mas também preciso importá-lo do StarIcon comum. Ótimo. Agora, vamos ver. Agora, temos a estrela aqui, que é obtida com a propriedade CSS do caminho do clipe. Mas você pode ver se eu clicar nele, se eu tentar começar o show, nada acontece. Precisamos torná-lo ativo de alguma forma. Precisamos informar aos usuários que esse show está começando. Anteriormente, usávamos renderização condicional, Star me e Unstar me. Mas agora, como temos componentes estilizados, podemos aplicar estilos dinâmicos com muita facilidade usando interpolação de cadeias de caracteres dentro de componentes estilizados. Acabei de passar essa função e especifico. Se tivermos props.active passado para o componente do ícone de estrela, aplique essa cor amarela. Caso contrário, aplique essa cor branca acinzentada. O que precisamos fazer aqui é simplesmente passar o suporte ativo aqui para o componente do ícone em estrela, que será isStarred. Quando isStarred for true, prop ativo será verdadeiro, o que significa que ele será usado dentro do componente de estilo para escolher a cor amarela. Quando for falso, será a cor cinza aqui. Vamos experimentar e ver. Eu salvo tudo. Agora, você pode ver que na verdade é amarelo porque esse programa agora é estrelado. Se eu clicar nele, os estilos serão alterados. Eu clico novamente, boom, o show é estrelado. Muito incrível. Legal. Nós terminamos com o ShowCard aqui. Agora, vamos passar para o nosso convidado. Aqui, também temos nosso último componente aqui dentro dos convidados ShowMainData. Na verdade, vamos copiar tudo daqui. Onde está? Ele simplesmente voou para longe. Vamos voltar ao ShowMainData. Na parte inferior, temos muitos componentes aqui, na verdade. Vamos para o topo e vamos ver. Primeiro, temos o MainDataWrapper. Essa será a div que envolverá tudo, então, abrindo o colchete, fechando o colchete. Boom, nós temos isso. Depois, temos o image-wrap e, por dentro, temos estilo de texto da imagem, o que significa que precisamos modificar um pouco a marcação aqui. Vamos adicionar um invólucro div adicional para a tag de imagem e className para o div será image-wrap. Legal. Agora, essa div aqui que envolve o resto da marcação será essa seção de dados que temos aqui. Vamos usá-lo. Ótimo. Agora, também temos o título e também temos o resumo e os gêneros. Nosso título será o invólucro para h1 div e span. É um pouco abstrato demais, mas o título será apenas a tag h1 aqui, aquela div e talvez o ícone de início que não usamos aqui anteriormente. Deixe-me encapsular h1 e div aqui. Temos o Headline, que agora tem o título, que tem a div com classificação, mas dentro da div também podemos adicionar, digamos, StarIcon. Deixe-me realmente usar rating.average aqui e, de acordo com nossos estilos, temos o elemento span dentro do mergulho, então podemos realmente envolvê-lo em um espaço. Então, aqui podemos usar o StarIcon que vamos importar do StarIcon comum. Vamos apenas chamar o componente StarIcon e deixar claro que ele estará sempre ativo. Sempre teremos a cor amarela. Eventualmente, a marcação ficará assim. Vamos experimentar e ver o resultado. No final, temos essa estrela amarela aqui que sempre estará amarela ao lado da classificação. Legal. Não parece ruim. Aqui também temos resumo e gêneros. O resumo será exatamente esse div estilizado e os gêneros também serão denominados div; vamos usá-lo, ou aquele div de embrulho ou talvez não. Os gêneros serão apenas a div que descarta o método.map. Vamos tentar ver, e agora basta ver em nossa página como ela é linda. É totalmente responsivo. Você pode tentar redimensionar a janela, acessá-la no seu celular. Ficará ótimo em todos os dispositivos. Volte para a página inicial, temos esta página estilizada. Temos quase tudo estilizado, mas perdemos algumas coisas. Por exemplo, você pode ver que essa lista de cartas, digamos, não tem nenhum estilo. Queremos ter uma rede. Vamos ver quais coisas não estilizamos aqui. Não definimos o estilo show grid, então voltamos ao ShowGrid. Aqui, para esse div, vamos usar esse componente de estilo reutilizável que criamos chamado FlexGrid. Vou usar esse FlexGrid dentro do ShowGrid e deixar eu fechar todos esses componentes porque temos muitos arquivos abertos. Eu volto para o ShowGrid. Aqui eu uso o FlexGrid e o importo de /common/FlexGrid. Incrível. Eu volto para a página e você vê que tudo parece bem. É totalmente responsivo e tem uma boa aparência. Agora, e quanto aos atores? Deixe-me procurar atores. Você pode ver que os atores não têm estilo porque nos esquecemos completamente deles. Vamos corrigir isso. Nós vamos aos atores aqui. Para o ActorCard, vamos importar esse componente comum do SearchCard do SearchCard comum que será o SearchCard e embrulhar tudo em um SearchCard se examinarmos o arquivo SearchCard. Também temos o SearchImageWrapper aqui, então, para o div que envolve a tag da imagem, usaremos SearchImageWrapper, que também é importado do SearchCard comum. Vamos ver, talvez precisemos mudar alguma coisa daqui de acordo com os estilos, mas não acho que não precisemos fazer isso. também precisamos usar o FlexGrid Na verdade, também precisamos usar o FlexGrid para criar uma grade com nossos cartões. Vamos ao ActorsGrid e, como antes, vamos usar o FlexGrid que foi importado do FlexGrid comum. Agora, veja isso. Parece incrível. Os atores são estilizados, os shows são estilizados, tudo parece incrível. Temos esse StarIcon, mas se formos para a página com estrela, também veremos que tudo parece bem porque dentro do componente Starred dentro da página Starred, usamos o componente ShowGrid reutilizável. Vamos ver o resto. O que temos aqui? Dentro de outras páginas, usamos também apenas algumas coisas. Por exemplo, dentro do Starred, usamos aqueles divs vazios sem nenhum estilo. Podemos substituí-los pelo componente sensorial de texto que está localizado dentro de uma pasta comum. Isso está na página favorita. Em vez de apenas mostrar div, nenhum programa foi estrelado. Vamos usar o TextCenter e esse TextCenter precisa ser importado de components/common/TextCenter'. Simples assim. Em vez desse div, vamos usar o TextCenter, ele mostra nosso TextCenter de carregamento. Em todo lugar está o TextCenter. O mesmo que provavelmente faremos. Deixe-me ver. Dentro do JSX doméstico, em vez de mostrar esse div e div sem resultados, vamos apenas mostrar TextCenter IntelliSense importado do TextCenter comum, sem resultados TextCenter, e acho que é isso. Deixe-me ver. Se eu for para casa e digitar algo completamente sem sentido , definitivamente não teremos resultados. Teremos esta mensagem aqui, sem resultados. Se formos para Favoritos e limparmos o armazenamento aqui e atualizarmos a página, veremos a mensagem Nenhum programa foi marcado com estrela. Finalmente, nosso aplicativo agora está totalmente estilizado. Temos tudo e cuidamos de todas as páginas do aplicativo. Ótimo. Agora vamos comprometer tudo aqui. Isso permitiria? Foi uma longa jornada neste vídeo. A mensagem de confirmação será estilizada, todo o aplicativo usará componentes estilizados. Incrível. No próximo vídeo, adicionaremos algumas coisas de estilo menor, digamos , ao aplicativo. Para torná-lo ainda mais interativo, isso vai ser interessante. Nos vemos lá. 87. 31 Estilando o aplicativo p3: Olá, parabéns por estilizar todo o aplicativo. Agora temos tudo pronto. No entanto, podemos melhorar algumas partes, para que fique um pouco melhor, na minha opinião. Em primeiro lugar, a primeira coisa gostaria de mencionar é que, sempre que procuramos cartas, elas simplesmente aparecem em nós. Não seria bom fornecer alguma animação quando esses itens aparecessem, por exemplo, animação fade-in. No registro do NPM, você pode encontrar esse pacote chamado react fade in, que é apenas um componente que você importa. Você o especifica da mesma forma que usamos componentes estilizados. Muito parecido com isso e, em seguida, fornece animação para seus elementos infantis. Eles desaparecem e desaparecem com o atraso. Este pacote é muito simples de usar, no entanto, ainda é um pacote. Quero dizer que, para um caso de uso tão simples, talvez não precisemos de nenhum pacote. Você pode simplesmente instalá-lo e não pensar em escrever nenhum CSS, mas menos pacotes você tem, melhor porque ele tem menos dependências em seu aplicativo. Primeiro, eu queria usar esse pacote, mas depois decidi que podemos realmente escrever apenas uma marcação CSS muito pequena que obterá um efeito muito semelhante. Se voltarmos à essência aqui, estilizando a parte de três pontos do arquivo MD, aqui você pode descobrir que, digamos, uma grade de bandeiras aprimorada que já temos dentro da grade flexível comum jsx com esta animação e quadros-chave. Deixe-me copiar tudo isso e substituí-lo. Agora, sempre que um componente de grade flexível for montado, ele terá essa animação de desvanecimento, conforme definido por esses quadros-chave. Isso apenas aumentará a capacidade de zero para um e obteremos um efeito muito semelhante ao react fading, mas sem demora. Vamos tentar ver. Agora, sempre que procuro atores ou programas, assim como sempre que uso o componente de grade flexível em algum lugar, você verá esse desvanecimento na animação em jogo, seja para shows , seja para atores, seja na página inicial. Efeito muito semelhante, mas sem qualquer dependência. Você também deve considerar que, no futuro, quando for instalar algo do npm, primeiro faça uma pergunta a si mesmo. Você realmente precisa dessa dependência ou pode fazer isso sozinho? Isso é muito importante quando você vai trabalhar em projetos reais. Ótimo. Agora, a próxima coisa que eu gostaria de acrescentar é que, sempre que começamos um show, agora, nossa estrela que temos aqui fica amarela. Isso não é ruim, mas podemos torná-lo mais fácil de usar e fornecer, digamos , uma animação quando começamos com um botão, quando iniciamos o programa, a estrela, na verdade, digamos que de alguma forma esteja sendo animada. Se voltarmos a isso aqui, também podemos encontrar isso na terceira parte do MD, que mostra a placa JSX com componente aprimorado no estilo StarBtn. Vamos aos shows, mostre o cartão. Aqui temos aquele StarBTN, se compararmos. Aqui definimos outra classe chamada Animate e temos algo novo aqui. Vamos copiá-lo e inspecionar o que temos. Em primeiro lugar, definimos essa classe animada, que também tem animação conforme definida por esses quadros-chave, mas também temos aqui essa interpolação e temos o ícone de estrela aqui, o que ela faz. Você sabe que dentro da marcação CSS, dentro do componente estilizado, podemos especificar, semelhante ao SAS, o aninhamento de elementos. Aqui, eu interpolei ícone Iniciar e isso significa que tudo o que eu interpolou aqui realmente se resolverá para componentes de estilo existentes como equipamento de referência. Dentro dessa classe animada, sempre que esse elemento StarBtn tem classe animada, dentro desse elemento StarBtn, deslocamos nosso ícone. Sempre que houver StarBtn, terá uma classe ativa, terá uma classe animada, por favor, estilize o componente de ícone de estrela, que é usado dentro dele. Dessa forma, podemos resolver iniciar especificamente o estilo do ícone. Esse elemento, sempre que StarBtn tem alguma classe. Vamos tentar ver. Gostaríamos de animar o nome da classe do componente StarBtn sempre que o programa estiver sendo iniciado. O que só vai especificar , por favor, quando o show começar, anexe a classe animate. Vamos tentar ver. Vamos voltar ao nosso aplicativo e você acabou de ver aquela animação. Sempre que clico no programa, agora ele está aumentando e diminuindo de tamanho. Funciona. Parece bom até agora, mas se formos para a página inicial e eu atualizar a página você ainda verá a mesma animação e eu não fiz nada. Isso ocorre porque quando o componente é montado, essa classe animada está sendo adicionada porque nosso show já começou e vemos a animação. Isso não é ruim, mas esse não é exatamente o comportamento que queremos alcançar. Só queremos executar a animação quando o componente foi realmente iniciado, não quando o componente está sendo montado. Para alcançar o resultado que queremos, vamos introduzir um novo gancho chamado use ref. O que é isso? Em primeiro lugar, vamos importá-lo do React. Esse é um dos ganchos integrados que você precisará durante sua futura carreira de desenvolvedor. O que é esse gancho? Use ref é apenas um gancho que você chama assim e esse gancho retorna uma referência. Uma referência que você especifica ou, digamos, associa essa referência a algum elemento. Vamos tentar ver. Por exemplo, queremos dar uma referência a esse StarBtn. Vamos chamar essa referência de StarBtn ref, sem mais nem menos. Agora, para associarmos essa referência, acabamos de chamar o gancho, obtivemos nossa variável de referência starBtn, mas ela ainda não está associada a nenhum desses elementos. Para fazer isso, precisamos passar para starBtn, um prop, na verdade um atributo chamado ref e para essa ref, especificamos, starBtn ref. Você pode simplesmente passar ref para seus componentes personalizados, digamos. Se eu tiver isso, deixe-me ver, por exemplo, o título do aplicativo que eu uso dentro do layout principal Não posso simplesmente passar ref e depois especificar outra coisa. A referência está sendo passada somente para elementos HTML nativos subjacentes. Se você quiser passar a referência para seus componentes personalizados, ela deve ser tratada adequadamente, e falaremos sobre isso no futuro. Mas, por enquanto, vamos nos limitar aos elementos nativos, já que StarBtn é basicamente apenas um elemento HTML nativo, porque, no fundo, ainda é apenas um botão. É um componente criado pela biblioteca de componentes estilizados e trata as referências adequadamente. Basicamente, o que quer que passemos aqui, seremos redirecionados para o elemento nativo HTML do botão subjacente. Passamos ref como starBtnRef. Agora, o que podemos fazer com isso? Por que faríamos isso? Vamos tentar refatorar manipulador onClick aqui que passamos para starBtn. Em vez de passar uma função que chama onStarmeClick, vamos criar uma função chamada handleStarClick que vamos criar aqui. HandleStarClick inside, que chamará OnStarmeClick e passará o ID para dentro. Mas também, vamos registrar o StarBtnRef no console e ver o que temos. Se abrirmos um console, sempre que eu clicar aqui, veremos o objeto com apenas uma propriedade chamada atual. Sempre que você cria uma referência como essa, você sempre tem um objeto, não importa o que aconteça, com a chave atual. Você pode ver que a propriedade atual aponta para o elemento do botão, para o elemento HTML chamado botão, não chamado de botão 2, apenas o elemento do botão subjacente. Na verdade, isso é equivalente a escrever document.getElementById, por exemplo. Quando você pega algum elemento por ID, isso é o equivalente. No React, sempre que você precisar acessar o elemento subjacente diretamente com a API DOM, em vez de usar document.getElementById, document.getElementByClassName, por outra coisa, você usaria referências e, em seguida, usaria starbtnRef.current e, em seguida, obteria seu elemento. Eu o salvo, StarBtnRef.current. Novamente, clico no botão, você verá que agora eu tenho esse elemento, o que significa que posso usar o que eu quiser aqui e brincar com ele usando a API DOM. Mas é importante associar elementos e passar a referência. Porque se eu não fizer isso, minha referência ficará vazia. Deixe-me tentar ver. Eu atualizo a página. Eu clico, agora meu starBtnRef.current me dá indefinido porque agora minha referência está vazia. Não estava associado a nada. Sempre que você usar ref, não esqueça de passar o atributo ref. Como agora temos StarBtnRef.current apontando para o elemento DOM subjacente, podemos usar a API DOM para manipular nossa lista de nomes de classe. Aqui, vou criar uma variável chamada, digamos, starBtnElement. Será starBtnRef.current. Em primeiro lugar, nossa corrente, como você acabou de ver, pode ser indefinida, então vamos fazer uma verificação segura aqui. Se starBtnRef.element for falso, saia dessa função. Caso contrário, continuamos e dizemos que, se o programa for estrelado, nesse caso, faça o seguinte. Acabei de notar que se chama início em vez de estrela. Deixe-me renomeá-lo para StarBtnElement. starbtnElement.classList.remove (animado). Caso contrário, chamamos star.btnElement.classList.add (animate). Em primeiro lugar, a lógica não se encaixa aqui. Em primeiro lugar, vamos ver se isso funciona e depois vamos discutir isso. Sempre que clico, você pode ver que meu programa está sendo estrelado e eu vejo a animação somente quando clico aqui. Mas se eu voltar a estrelar, ainda tenho aquela animação. Isso ocorre porque eu uso esse className aqui. Deixe-me removê-lo. Agora vamos tentar ver. Nenhuma animação é executada no momento. Deixe-me voltar para a página inicial. Mas quando estou tentando estrelar o programa, você pode ver que a animação está lá. Por que usamos essa lógica aqui? Quando essa função for executada, isStarred ainda estará no estado anterior. Basta lê-lo, pois o código está escrito aqui. Nosso programa está atualmente estrelado. Quando clicamos nele, não queremos rodar nenhuma animação. Quando nosso programa está atualmente estrelado e quando o desestrelamos, removemos a classe animate. Não queríamos rodar nenhuma animação aqui. Mas se nosso programa atualmente não é estrelado, essa outra condição dispara. Nesse caso, adicionamos a classe animate para fornecer a animação. Dessa forma, usando a API DOM, usando o arco useRef, podemos manipular nomes de classes diretamente, digamos, usando imperativamente a API DOM em vez de usar a interface className que o React nos fornece. Assim, podemos adicionar animação e conhecemos o novo gancho chamado UseRef. Novamente, para resumir rapidamente, useRef pode ser usado como referência para elementos HTML nativos subjacentes, caso você queira obter acesso à interface DOM desse elemento, algo assim. Vamos adicionar tudo ao palco e nos comprometer. Primeiro, na verdade, não usamos o pacote React Fade-In. Usamos nosso CSS simples para obter um efeito de fade-in muito semelhante. Então, em vez de usar apenas className para fornecer animação para o elemento estrela, usamos o gancho useRef para obter acesso ao elemento DOM subjacente. Em seguida, usamos essa API DOM, propriedade classList do elemento DOM para adicionar e remover a classe animate de forma imperativa para adicionar ou remover a animação, que é definida dentro de nosso componente estilizado. Agora, podemos confirmar isso e dizer, adicionar animação ao FlexGrid. Digamos que adicionou animação fade-in ao FlexGrid. Adicionou animação StarBtn ou, digamos, adicionou animação em escala ao StarBtn. Incrível. É isso por enquanto. Eu vou te ver na próxima. 88. 32 implantação para o Github Pages: Olá. Neste vídeo, finalmente implantaremos o Box Office, então, no final, teremos um URL disponível publicamente que podemos compartilhar com nossos amigos. No projeto anterior, no Tic Tac Toe, usamos um serviço chamado Search.SH, desta vez vamos tentar algo novo. A hospedagem que vamos usar será o GitHub Pages. Por que GitHub Pages e não Search? Em primeiro lugar, eles são muito parecidos, ambos são usados para hospedar arquivos estáticos, mas queremos explorar , experimentar coisas novas, queremos ver alternativas. No final, você poderá comparar o que você mais gosta, GitHub Pages ou o Search, ou talvez até algo mais. Vamos embora. Em primeiro lugar, vamos navegar até a documentação do Create React App. Se clicarmos em “Começar”, à esquerda, podemos procurar a seção de implantações. Dentro da seção de implantação podemos procurar o GitHub Pages. O que vamos fazer é seguir esse simples tutorial passo-a-passo. A primeira coisa que ele nos pede é abrir package.json e adicionar o campo da página inicial para o seu projeto. Vamos fazer isso. Vou apenas copiar a página inicial, abrir package.json, em qualquer lugar do package.json vamos adicionar a página inicial. Mas aqui precisamos mudar algumas coisas. Em primeiro lugar, meu nome de usuário.github.io. Meu nome de usuário deve ser substituído pelo seu nome de usuário no GitHub. Vou pegar o meu. Meu aplicativo precisa ser substituído pelo nome do seu repositório no GitHub. No meu caso, será box-office-app. Eventualmente, o URL para mim ficará assim. Muito parecido, deve ser para você também. Eu salvo package.json, volto ao tutorial. Vamos ver a etapa número 2. Em seguida, precisamos instalar um pacote chamado gh-pages e, em seguida, adicionar um script de implantação ao package.json. Vamos primeiro instalar a dependência. Vou apenas copiar o comando. Vou parar meu aplicativo e, em seguida, executar o comando de instalação. Durante a instalação, vamos ver o que precisamos para empacotar. json. Precisamos adicionar mais dois scripts, implantar e pré-implantar. Vamos copiá-los. Vamos voltar para package.json. Até agora, já temos a dependência instalada. Vamos navegar até os scripts e, no final, adicionar pré-implantação e implantação. Não precisamos de nenhuma vantagem que tenha sido copiada, salvamos e aqui o que vemos. Temos o script de implantação definido e, em seguida, temos a pré-implantação. Digamos que o Npm seja inteligente o suficiente para entender que pré-implantação deve ser executada antes do script de implantação. Portanto, sempre que executarmos o script de implantação, o predeploy será executado. Predeploy construirá o aplicativo, a compilação do aplicativo será produzida na pasta build e, em seguida, especificamos que implante a pasta build aqui, para que a compilação que você vê na linha 35 se refira a essa pasta de construção dentro da raiz do nosso projeto. Então, se avançarmos no tutorial, se você estiver implantando em uma página de usuário do GitHub, observe que esse não é o nosso caso. terceira etapa é apenas executar npm run deploy. Vamos tentar fazer isso. Agora podemos fazer npm run deploy. Vamos ver a saída. Primeiro, vemos o npm run build, vem do script de pré-implantação, depois temos o gh-pages menos o comando build, e agora diz publicado, mas não temos nenhum URL, onde precisamos ir? A página inicial que especificamos em package.json é na verdade, a URL que precisamos visitar para acessar nosso aplicativo. Vamos copiar esse URL. Vamos abri-lo em uma nova guia. Mas assim que navegarmos aqui, veremos que não foi encontrado, é 404. Então, o que acontece? Vamos investigar. Se voltarmos ao nosso repositório, aqui está uma coisa que eu não mencionei anteriormente, é que o GitHub Pages está disponível gratuitamente apenas para repositórios públicos. No meu caso, o repositório é privado. Ele está marcado aqui no canto superior esquerdo, Privado, então, para usar o GitHub Pages gratuitamente, preciso ter certeza de que esse repositório é público. Vamos para Configurações e, nas Configurações, mudaremos a visibilidade do nosso repositório de privado para público. Vamos para a página de configurações, rolamos até o final e, aqui, em Danger Zone, alteramos a visibilidade do repositório transformamos em público. Sim, eu quero tornar isso público. Sim, tenho certeza. Ele também pode solicitar sua senha, tudo bem. Agora meu repositório se tornou público. No entanto, se tentarmos acessar o URL novamente, ele ainda será o mesmo, não encontrado. Precisamos instruir a hospedagem, precisamos instruir o GitHub Pages de que queremos publicar nosso aplicativo agora. Em primeiro lugar, como isso funciona? Se formos para a página principal do repositório aqui, veremos duas ramificações agora disponíveis. Anteriormente, era apenas um. No momento, se clicarmos nessas duas ramificações, veremos a ramificação gh-pages aqui. Se clicarmos nessa ramificação, você verá todos os arquivos que temos dentro da pasta build. Basicamente, o comando deploy aqui, o que ele fez, usou aquela pasta build, criou uma nova ramificação em nosso repositório e carregou todos os arquivos da pasta build para a ramificação gh-pages no GitHub. A forma como a hospedagem do GitHub Pages funciona é que ela usa uma de suas ramificações em seu repositório e todos os arquivos que estão localizados aqui são hospedados nos servidores do GitHub. Dessa forma, podemos hospedar arquivos que estão localizados dentro do nosso repositório. Para configurar corretamente o GitHub Pages para direcionar a hospedagem para essa ramificação específica do gh-pages para esses arquivos, precisamos novamente acessar a página Configurações do nosso repositório. À esquerda, procuramos a seção Páginas, a página Páginas, e aqui especificamos que, ok, fonte para nossa implantação será implantada a partir de uma ramificação. Por padrão, isso é o que você deve ter por enquanto e, para a ramificação, você especifica que hospede nossos arquivos a partir da ramificação gh-pages. Clicamos em “Salvar” e logo após a implantação ser acionada. Agora, levará alguns minutos, um minuto ou dois para implantar todos os seus arquivos do gh-branch em seu repositório para a hospedagem. Se formos para Ações aqui, aquela guia Ações em seu repositório, aqui você verá agora esse único fluxo de trabalho sendo executado. Se você clicar nele, verá o progresso da sua implantação. Quando terminar, você verá uma marca verde aqui, que significa que seu aplicativo será publicado aqui, sob esse URL. Vamos esperar até que esteja pronto e eu entrarei em contato com você. Agora parece que nosso aplicativo foi implantado. Você pode ver que tudo está verde. Agora eu também tenho esse URL que apareceu aqui. Se eu clicar nele, é isso que eu vejo. Em primeiro lugar, meu aplicativo, como estava anteriormente, está disponível na mesma URL que você especificou na página inicial, chave da página inicial dentro de package.json. Mas se o acessarmos, veremos Não encontrado. Por que isso? O fato é que ele realmente foi implantado, mas por algum motivo diz que não foi encontrado, e definitivamente vem de nosso aplicativo, porque se inspecionarmos a marcação, isso se assemelha ao nosso aplicativo, o que temos dentro do index.html, nosso esqueleto. Dentro do público, temos esse esqueleto. É nosso. Temos a mesma cabeça, temos tudo o mesmo. Mas o que aconteceu? O fato é que, se voltarmos ao tutorial na documentação do Create React App, ele terá essa nota chamada Notes, sobre roteamento do lado do cliente. O problema é que a hospedagem do GitHub não está realmente configurada para lidar com aplicativos do lado do cliente, para não lidar com aplicativos de página única que usam roteamento do lado do cliente. Na verdade, você pode ler mais informações aqui dentro da documentação oficial. Vamos usar algo chamado HashRouter, do React Router. Essa é uma das soluções fornecidas aqui. Vamos fazer isso. Voltamos ao aplicativo, abrimos o código, App.jsx. Aqui usamos o BrowserRouter, que é importado do React Router dom. Em vez disso, podemos usar algo chamado HashRouter, e pronto. O resto estará no React Router dom. Não precisaremos de etapas extras para isso. Para entender o que ele faz, vamos primeiro executar o servidor de desenvolvimento local novamente, npm run start. Isso é o que temos agora. Em primeiro lugar, nosso aplicativo agora, apesar de ser servido localmente, está disponível sob o prefixo /box-office-app, qualquer prefixo que especificamos na página inicial do pacote JASON. Criar um aplicativo React é inteligente o suficiente para entender que podemos implantar sob o prefixo do aplicativo de bilheteria. É por isso que é mantido aqui. Mas quando você serve aplicativos sob prefixo, você precisa considerar isso como sua URL base. O que quero dizer com isso, se procurarmos, mostra, por exemplo, que aqui, se passarmos o mouse em ler mais, vamos para a página /show/show ID. Quando pudermos hospedar no GitHub, nosso URL ficará assim : /box-office-app/show/show ID. Mas não teremos esse prefixo, assim como temos aqui no host local. Será problemático porque, caso contrário, nossa página não será encontrada. O que quero dizer com isso é que vamos primeiro implantar o aplicativo e você mesmo o verá, e depois corrigiremos isso com uma adição muito pequena ao nosso código existente. Acabei de executar o script de implantação novamente. Novamente, ele cria meu aplicativo e publica novamente no GitHub Pages. Se voltarmos ao repositório na guia Ações, veremos novamente outro fluxo de trabalho em execução. Nós apenas esperamos até que ele seja implantado e depois vamos fazer o check-out. Está implantado agora. Vamos voltar ao aplicativo. Se voltarmos ao nosso aplicativo, ainda veremos não encontrado. Mas se eu atualizar, agora temos o aplicativo. Parece perfeitamente bom. No entanto, se você olhar o URL, agora temos esse hash aqui. Ele será usado para lidar adequadamente com roteamento do lado do cliente quando implantarmos no GitHub Pages. Mas ainda temos mais um problema que acabei de mencionar anteriormente sobre o link, sobre esse botão Leia mais. Se eu clicar nesse botão, você verá que navegamos até /show/show ID. Não temos o prefixo do aplicativo de bilheteria e, por isso, temos 404. Para resolver o problema, precisamos primeiro entender por que isso acontece. Vamos ler mais e marcar. Serão componentes, shows, cartões de exibição. Aqui, usamos uma tag âncora simples que aponta para /show/show ID. Tudo bem e funcionará. Funcionará se nosso aplicativo for servido sob a rota, não sob o prefixo. Precisamos consertar isso de alguma forma. Uma solução ingênua é inserir manualmente qualquer prefixo que você tenha aqui. Vai funcionar, mas essa não é uma boa solução. Precisamos, de alguma forma resolver automaticamente qualquer prefixo que tenhamos aqui. React Router cuida disso. No passado, substituímos o componente de link que usamos do React Router por essa verificação de âncora porque realmente não precisávamos desse componente de link. No entanto, agora vamos recuperá-lo novamente. Vou importar o link do React Router dom. Então, em vez da tag âncora, vou usar um link novamente, mais uma vez. Em vez de href, vou especificar to e vou manter o alvo em branco e os atributos de relacionamento. Dessa forma, ainda teremos o mesmo link de antes, mas desta vez o componente de link do React Router dom cuidará do prefixo. Ele será automaticamente resolvido para o URL correto. Agora, vamos tentar executar o script de implantação novamente, reimplantar o aplicativo e ver o resultado final. Te vejo assim que for implantado. Eu esperei mais um minuto. Aqui está minha terceira implantação que acabou de ser publicada há um minuto. Vou voltar ao meu aplicativo. Eu vou me refrescar. Eu procuro programas e agora, se eu clicar em Leia mais, agora minha URL foi resolvida corretamente porque agora era gerenciada pela biblioteca React Router. Assim, conseguimos implantar nosso aplicativo. Parabéns. Agora, vamos voltar ao nosso código e confirmar tudo. Em primeiro lugar, instalamos biblioteca gh pages para implantar no GitHub Pages, o campo da página inicial no pacote JSON especifica exatamente onde o aplicativo será implantado. Novamente, implantamos a pasta build que é produzida pelo comando npm run build. Agora, também substituímos o roteador do navegador pelo roteador de hash porque o GitHub Pages não lida adequadamente com hash porque o GitHub Pages o roteamento do lado do cliente. Uma maneira de corrigir esse problema é usar o roteador de hash conforme sugerido na documentação do aplicativo Create React. Em seguida, também mudamos uma tag âncora simples para o componente de link do React Router dom porque precisamos resolver o prefixo depois que nosso aplicativo for implantado no GitHub Pages. Vamos adicionar tudo ao estágio e vamos nos comprometer e dizer implantar, implantar o aplicativo no GitHub Pages, usar o HashRouter, usar o link em vez da tag âncora nativa. Legal. Eu coloco tudo para masterizar, volto ao meu repositório para garantir que tudo seja implantado. Minha última mudança, 10 segundos atrás. Eu tenho uma segunda filial chamada gh pages. Sempre que você executa o npm run deploy, ele atualiza o GitHub Pages e atualiza os arquivos hospedados em sua URL que você pode usar para compartilhar com seus amigos. Mais uma coisa simples que eu acrescentaria aqui é que podemos realmente usar esse URL para onde nosso aplicativo está. Vamos visitá-lo mais uma vez. Sim, está realmente aqui. Podemos adicionar esse URL à nossa seção Sobre na página do repositório. Eu clico no sinal de Configurações aqui. No site, adiciono o link e clico em Salvar alterações. Agora, boom, aparece aqui. Isso é apenas para você acessar facilmente seu aplicativo no futuro. É isso por enquanto, nos vemos na próxima. 89. 33 PWA (Progressive Web App): Olá de novo. No último vídeo, finalmente implantamos a bilheteria em um ambiente vivo. Desta vez, vamos falar sobre trabalhadores de serviços. Como você se lembra, no primeiro vídeo em que criamos esse projeto, temos o prestador de serviços, o registro do prestador de serviços, assim como o ponto de registro do prestador de serviços no registro, e eu disse que falaremos sobre isso mais tarde. Agora, essa é a hora. Esse prestador de serviços é necessário para criar nosso aplicativo, para fazer bilheteria em um aplicativo web progressivo. O que é um aplicativo web progressivo? Um aplicativo web progressivo é qualquer outro aplicativo da web, qualquer outro site que segue uma lista de itens específicos e, quando o aplicativo DevUp do site preenche essa lista de opções, esse site se torna um aplicativo web progressivo. Isso significa que o aplicativo fica disponível off-line. O aplicativo pode ser instalado como aplicativo móvel real, esteja você no desktop ou no dispositivo móvel. A questão aqui é: quais são essas opções que tornam um site um aplicativo web progressivo? No navegador Chrome, se você acessar as ferramentas de desenvolvedor do Chrome, se expandir esta seção à direita, poderá ir para a seção farol. Lighthouse é uma ferramenta embutida no navegador Chrome. Ele nos permite avaliar o desempenho do site medindo sua velocidade , tempo de espera e algumas métricas diferentes. Aqui, nas categorias, temos essa verificação progressiva de aplicativos da web. Vamos chegar lá e clicar em Analisar carregamento de página e ver o que vai acontecer. Levará apenas alguns segundos até que ele audite o site e agora sabemos que temos quase tudo verde perfeito, mas não estamos realmente interessados em nenhum deles. Se estiver, você pode facilmente ir uma a uma, expandir seções diferentes e ler o que pode ser melhorado, o que pode ser alterado. Talvez você não precise mudar nada, mas na parte inferior, você terá a seção PWA, um aplicativo web progressivo. Uma lista de coisas que você vê aqui é basicamente o que o site precisa seguir para se tornar um aplicativo web progressivo. Em primeiro lugar, não temos algumas coisas aqui. Nosso aplicativo não é instalável, portanto, para torná-lo instalável, precisamos apresentar um service worker. O que é um prestador de serviços? Assistente de serviços, na verdade é mais fácil quando eu vou visualizá-lo. Temos o site aqui. Nosso site aqui à esquerda. Então, à direita, temos solicitações de saída. Simples assim. Talvez vamos inspecionar isso nós mesmos, então vamos até a guia de rede e, quando atualizamos a página, vemos uma lista de solicitações, então este é nosso navegador que faz uma solicitação ao servidor de páginas do GitHub para obter o índice HTML, para obter arquivos CSS JavaScript do servidor de hospedagem. Um prestador de serviços é apenas um script. Ele está dentro do navegador, em algum lugar dentro do navegador, fora do nosso agente de serviços de aplicativos e, o que faz, simplesmente intercepta todas essas solicitações, solicitações de saída e faz algo com elas. No nosso caso, o service worker será apenas um proxy que interceptará todas essas solicitações de saída e as colocará no armazenamento em cache dentro do navegador. Assim próxima vez que esses arquivos forem acessados, em vez de deixá-los passar, service worker usará o armazenamento em cache recuperará todas essas solicitações, todos os arquivos que foram recuperados anteriormente a partir do armazenamento em cache, e disponibilize-os em nossa página da web. Dessa forma, nosso aplicativo pode ficar disponível off-line, que significa que qualquer solicitação enviada, o service worker a interceptará. Ele verificará o cache e se essas solicitações estiverem presentes no cache, elas serão atendidas a partir do cache pelo service worker. Para resumir rapidamente, um service worker é apenas um script em algum lugar dentro do navegador. É apenas um proxy que intercepta solicitações de saída do navegador. Algo parecido. Se voltarmos ao nosso aplicativo, veremos que temos o arquivo JS do service worker aqui. Esse é o script em si, o próprio service worker, que será executado dentro do navegador, fora do nosso aplicativo. Esse arquivo que você vê aqui ficará em algum lugar dentro do navegador. Mas a questão é: como podemos lidar com isso? Como podemos realmente fazer algo com isso. Antes de podermos responder a essa pergunta, temos uma caixa de trabalho aqui. O que são essas e, se olharmos dentro do pacote Json, temos muitas dependências da caixa de trabalho. Essas são basicamente apenas bibliotecas que nos permitem, de alguma forma, escrever facilmente alguma lógica dentro do script do service worker. Você pode ver que esse script foi gerado automaticamente criando o aplicativo React e a lógica escrita aqui simplesmente intercepta todas as solicitações e as coloca no armazenamento em cache. Nós realmente não precisamos pensar muito nisso. Não vamos escrever nossa própria lógica para o service worker aqui, vamos usar a lógica existente e será suficiente armazenar tudo em cache, e será suficiente armazenar tudo em cache e a caixa de palavras é apenas um conjunto de funções que importamos e usamos para conseguir isso. Como esse arquivo foi gerado pelo aplicativo Create React, não vamos modificá-lo, não estamos interessados nele. Novamente, isso será suficiente. Agora também temos o registro de prestador de serviços. Para que o navegador entenda que queremos de alguma forma usar esse JS do service worker, precisamos registrá-lo dentro do navegador porque, se quisermos colocá-lo como parte de nosso aplicativo, nada acontecerá, então precisamos alguma forma registrar esse service worker nosso aplicativo e esse registro do service worker tem duas funções aqui. A primeira função é chamada register, que foi exportada daqui e segunda função é chamada de unregister. Novamente, toda essa lógica é gerada automaticamente ao criar o aplicativo React e será novamente suficiente para nosso caso de uso. A função de registro registrará o JS do service worker quando nosso aplicativo executado e a função de cancelamento de registro cancelará o registro do service worker existente em nosso aplicativo. Se olharmos dentro do índice jsx, aqui inserimos tudo como prestador de serviços a partir do registro do prestador de serviços. Isso significa que objeto de importação do registro do service worker, temos duas funções, registrar e cancelar o registro e, o tempo todo, era realmente cancelar o registro para nós porque não estávamos interessados no service worker. Para registrar um prestador de serviços, precisamos chamar a função de registro. No entanto, se você for usar o registro, ele funcionará em ambos os ambientes quando você for desenvolver localmente e quando for implantado ao vivo , digamos, na hospedagem de páginas do GitHub. Mas como ele usará cache e a estratégia de cache aqui é agressiva, isso significa que ele armazenará tudo em cache , então o que eu sugiro façamos é primeiro verificar se estamos atualmente no desenvolvimento local, não queremos chamar essa função de ponto e registro. Mas se estivermos dentro de um ambiente ao vivo, então, por favor, sim, chamamos a função de registro. Como podemos verificar isso e como podemos finalmente ver como isso funciona? Dentro do aplicativo, temos acesso a algo chamado process.env. Esse é apenas um conjunto de variáveis de ambiente às quais temos acesso. ambiente são variáveis definidas globalmente pelo ambiente em que nosso código é executado. Vamos tentar o console log process.env, e se eu digitar dot, tenho intellisense aqui, tenho node ENV. Se eu passar o mouse, você pode realmente ver que ele tem três valores potencialmente diferentes: desenvolvimento, produção e teste. Mas no nosso caso, ainda vamos cancelar o registro para ver. Digamos que o ENV atual seja atual e, por enquanto, ainda cancelaremos o registro. Vou executar o servidor de desenvolvimento local e também vou corrigir esse problema não definido vindo do ESLint porque o protesto é algo executado no lado do node JS, não no JavaScript executado dentro do navegador, então precisamos deixar o ESLint entender que também executamos dentro do ambiente node.JS, não apenas dentro do navegador. Node true, esse node true, vamos deixar o ESLint entender que estamos dentro do ambiente JS do node agora. Isso não fará nada , exceto que apenas removerá esse erro. É isso. Eu executo meu aplicativo localmente. Se eu for ao console, vejo que o ENV atual é igual ao desenvolvimento. O que vou executar o comando build aqui para criar uma compilação de produção esse nó variável ENV será definido no momento da construção, então, quando usamos o servidor de desenvolvimento local, isso é compilação de desenvolvimento. O aplicativo foi criado, mas logo abaixo do capô, não vemos isso. É por isso que vemos o node ENV definido para desenvolvimento, porque esse é nosso desenvolvimento construído e, novamente, essa variável é definida durante o tempo de construção. Quando executarmos o comando build, nosso aplicativo terá o node ENV definido para produção e podemos realmente usar essa variável para registrar ou cancelar o registro do service worker. Vamos tentar fazer isso. adicionar uma condição simples aqui. Se process.env.node ENV for igual a produção, nesse caso, ligue para registro de prestador de serviços e registre-se. Legal. Agora, vamos tentar reimplantar o aplicativo. Depois de implantado, veremos como tudo mudou. vejo lá em um segundo. Olá de novo. Agora nosso aplicativo está implantado. Meu primeiro fluxo de trabalho de implantação aqui. Agora voltamos ao nosso aplicativo e, se o atualizarmos, agora algo foi alterado. Em primeiro lugar, temos esse ícone de instalação aqui na barra de pesquisa, mas vamos tocá-lo em um segundo. Estamos interessados na guia Aplicativo aqui. Se formos para a seção Service Worker aqui, agora temos service-worker.js. Este service-worker.js foi novamente registrado por função de registro que é importada do arquivo ServiceWorkerRegistration. Essa é a função de registro, acesse "service-worker.js”, que está disponível no box-office-apps/service-worker.js. É o registro, aquele service worker dentro do navegador quando nosso aplicativo foi acessado e agora esse service worker está em execução, o que significa que agora o service worker está ativo e intercepta todas as solicitações enviadas e as armazena em cache dentro do navegador. Você pode ver que, se eu atualizá-lo novamente, meus arquivos, por exemplo, aquele índice HTML, serão fornecidos pelo ServiceWorker, assim como o resto dos arquivos aqui. Deixe-me “Esvaziar o cache e recarregar com força”. Faça isso de novo. Na verdade, nada mudou, mas ainda assim o aplicativo está sendo servido pelo ServiceWorker. Se eu não estiver errado, está em algum lugar dentro do armazenamento em cache aqui. Você pode vê-lo na seção de cache na guia Aplicativo. Em Armazenamento em cache, agora você vê onde a caixa pré-armazena os arquivos que estão sendo armazenados dentro do cache. Assim, podemos administrar o Farol. Comande novamente e veja o que temos até agora para uma lista de verificação progressiva de aplicativos web. Vamos embora. Estamos auditando meu aplicativo. apenas alguns segundos, vamos até o final e agora vemos que o aplicativo web progressivo agora pode ser instalado e não está realmente otimizado. Bem, na verdade está otimizado, mas só temos um ponto aqui. Manifest não tem um ícone mascarável, mas vamos corrigir isso no próximo vídeo, quando vamos personalizar o ícone, o nome do nosso aplicativo e o resto de algumas coisas. Por enquanto, podemos ver que nosso aplicativo é instalável. Nesse ícone que vemos aqui no canto superior da barra de pesquisa, podemos clicar nele e instalar nosso aplicativo como se fosse um aplicativo nativo. Se você estivesse em um dispositivo móvel, você também teria o pop-up ao acessar seu aplicativo para um dispositivo móvel. Você verá o pop-up de que, Ei, você pode realmente instalar este site como um aplicativo. Se você clicar em “Instalar”, o site será adicionado à sua tela inicial como se fosse um aplicativo nativo. Agora, se eu voltar para o meu desktop, aqui, tenho esse aplicativo chamado Create React App Sample. No momento, ele tem esse nome estranho porque é o que está especificado arquivo de manifesto que vamos personalizar no próximo vídeo. Mas o fato é que agora isso é um aplicativo, é instalável. Se eu clicar nele, você pode ver que agora ele não abre dentro de um navegador. Ele se abre dentro de sua própria janela como se fosse um aplicativo real nativo. Funcionará muito bem , como funcionava anteriormente. Muito legal. Você pode ver que ele realmente abriu aquela nova guia dentro do navegador. Esse é o problema dos aplicativos web progressivos. Idealmente, você não deve abrir nada dentro de novas guias, mas deve usar a guia atual e usar apenas, digamos, uma página para navegação sem usar novas guias. Mesmo assim, agora temos o aplicativo que é executado como um aplicativo nativo. Tudo isso foi conseguido usando o ServiceWorker, que nos deu a lista de verificação verde para aplicativos web progressivos. Resumindo, um aplicativo web progressivo é apenas um aplicativo da web, que segue uma lista específica de itens. Por exemplo, ele deve ter um service worker, o aplicativo deve usar algum cache para que possa estar disponível offline. Então, ele também deve ser servido a partir de HTTPS e algumas outras coisas que você pode encontrar dentro do Lighthouse. Vamos tentar ver novamente. O que mais temos aqui? Várias guias estão sendo abertas. Deixe-me atualizá-lo. O que você quer? Analise o carregamento da página. Vamos ver rapidamente a lista novamente. Dentro da lista, temos, deixe-me ver, a cor do tema, tela inicial personalizada configurada, o ícone de toque, aquela tag específica da janela de visualização e aquele manifesto que cuidaremos em breve, prestador de serviços. Todas essas coisas tornam um site, aplicativo web progressivo, tão simples quanto isso. Mais uma vez, o service worker que foi registrado como proxy dentro do navegador para interceptar a solicitação é o cerne de tudo isso. Somente porque, como prestadores de serviços, conseguimos obter essa seção instalável aqui. Nosso aplicativo agora se tornou instalável e também está disponível offline. Acho que ficou bem claro o que exatamente é um aplicativo web progressivo, o que é service worker e como tudo funciona aproximadamente. Por fim, vamos voltar ao nosso aplicativo e confirmar as alterações que fizemos. Primeiro, editamos o Eslintrc, para que possamos usar o process.env sem nenhum aviso ou erro, e verificamos. Se estivermos na fase de construção, use ServiceWorkerRegistration.register. Isso registrará esse arquivo service-worker.js dentro do contexto do navegador. Legal. Vamos fazer essas mudanças. Habilite o prestador de serviços no ambiente de produção. Eu atualizo meu repositório do GitHub e pronto por enquanto. No próximo vídeo, vamos lidar com o problema que vimos no Lighthouse, então ele ficará 100% verde. Te vejo lá. 90. 34 Corrigindo URL base para resolver imagens corretamente no Github Pages: Olá. No último vídeo, criamos aquele ótimo aplicativo web progressivo chamado Box Office. Mas aqui está um problema que eu realmente esqueci e é novamente sobre o URL base dentro do nosso aplicativo. Se você percebeu quando procura programas específicos e quando eles não têm uma imagem, tentamos exibir essa imagem não encontrada em PNG. No entanto, todos os nossos arquivos são exibidos sob o prefixo do aplicativo Box Office na hospedagem do GitHub Pages. Mas essa imagem não carregada porque você pode ver que ela é sempre 404 porque ela não existe no caminho que tentamos carregar. Não especificamos o prefixo. Como podemos realmente consertar isso? Se voltarmos ao nosso aplicativo e procurarmos uma imagem não encontrada, especificaremos exatamente assim. Apenas um caminho estático específico. Mas, como temos o prefixo, precisamos entendê-lo de alguma forma. Uma maneira de corrigir isso é, em vez de usar a imagem dentro da pasta pública, podemos colocá-la dentro da pasta de origem e usá-la como se fosse, digamos, um módulo. Em seguida, ele será processado pela configuração subjacente do Webpack e o caminho base será resolvido automaticamente. A mesma coisa que fizemos com tag âncora e o componente de link. Bem, pelo menos a ideia é a mesma. Vou apenas mover a imagem não encontrada para algum lugar, digamos, para a pasta da biblioteca, imagem não encontrada PNG. Agora, em vez de referenciar PNG de imagem não encontrada em todos os lugares, vou apenas importar imagem não encontrada da biblioteca, imagem não encontrada PNG. Talvez eu a nomeie como fonte de imagem não encontrada e vou especificá-la assim. Em seguida, copiarei essa importação e farei a mesma importação em todos os lugares. Aqui, isso é o que eu também acabei de fazer no elenco interno. Aqui, deixe-me ver o caminho correto. Voltamos para uma pasta, segunda pasta, biblioteca, imagem PNG não encontrada. Especificamos a fonte da imagem não encontrada, o mesmo que faremos dentro da grade de exibição. Importe a fonte de imagem não encontrada de. Voltamos novamente, voltamos à biblioteca, imagem não encontrada PNG, fonte não encontrada e o mesmo. Por fim, faremos isso dentro do ShowMainData. Fonte de imagem não encontrada na biblioteca, imagem PNG não encontrada. Agora, vamos tentar reimplantar o aplicativo e ver exatamente como isso se refletirá em nosso código final. Nos vemos em um minuto assim que esse código for implantado. Agora, o aplicativo foi implantado com sucesso. Vamos voltar ao nosso aplicativo. Agora, vamos atualizar a página. Nossa última pesquisa foi “Olá”. Nós o procuramos novamente. Desta vez, também vemos que não foi encontrado. Por que isso? O problema é que nossa imagem agora, nossa imagem anterior, é veiculada pelo Service Worker. Não foi atualizado. Ele é servido a partir do cache, o que significa que precisamos limpar o cache para ver as atualizações. Vou clicar com o botão direito do mouse no botão Atualizar no canto superior esquerdo e clicar em “Esvaziar cache” e “Hard Reload”. Como alternativa, posso ir até a guia Aplicativo, acessar Armazenamento e clicar em “Limpar dados do site”. Isso limpará todo o cache dentro do navegador especificamente para este site. Deixe-me clicar em “Limpar dados do site”. Então eu apenas refresco. Então eu procuro por “Olá”. Desta vez, nosso aplicativo foi resolvido com sucesso. Você pode ver que, em vez do URL real, vemos essa imagem de dados de base 64. O que é isso? Novamente, como nossa imagem foi trazida até nós pelo aplicativo Create React, a configuração subjacente do Webpack cuidou disso. Dentro da documentação do aplicativo Create React, foi mencionado em algum lugar que, se a imagem tiver um tamanho menor do que o limite específico, em vez de, digamos, processar o arquivo e servir o arquivo dentro da pasta pública. A imagem é convertida para formato base 64 e, em seguida , digamos que, em linha, essa sequência longa represente nossa imagem, não como um arquivo, mas como uma string. Muito legal. Agora tudo parece bom até agora. No próximo vídeo, conforme prometido, daremos um toque final ao aplicativo. Vamos usar ícones personalizados, nomes personalizados, para que nosso aplicativo seja perfeito. Nos vemos lá. 91. 35 toque final: Olá. Neste vídeo, finalmente daremos um toque final em nosso aplicativo. Vamos criar ícones, vamos mudar os títulos para que o aplicativo seja finalmente perfeito. Vamos embora. Mas antes de fazermos isso, vamos realmente confirmar as mudanças que fizemos no vídeo anterior. No vídeo anterior, como você se lembra, resolvemos nosso problema com a imagem. Vamos adicionar tudo rapidamente ao palco e, em seguida, confirmar tudo dizendo que imagem não encontrada foi movida do público ou simplesmente mover a imagem não encontrada para a fonte e importá-la em vez de vê-la da pasta pública. Muito longo, mas vale a pena. Então eu pressiono tudo para dominar e finalmente vamos voltar aos nossos ícones. Em primeiro lugar, precisamos escolher um ícone que usaremos dentro da guia aqui. Se voltarmos para o convidado que temos para a bilheteria, aqui temos esse ícone de dinheiro que preparei para nós. Podemos simplesmente baixar esse ícone aqui. Vou colocá-lo na pasta Downloads. Em seguida, precisamos gerar um conjunto de ícones que vamos colocar na pasta pública. No momento, temos esses ícones básicos de reação que agora podemos substituir, mas primeiro precisamos gerar esse conjunto de ícones. Normalmente, o que você faria é primeiro decidir sobre um ícone que deseja usar. Pode ser seu, por exemplo. Não é obrigatório usar esse específico. Se você tiver o seu, fique à vontade para usá-lo. Nós vamos para Resources.md. Aqui na parte inferior, podemos encontrar esse gerador de favicon que deixei para nós. Nós vamos para essa página. Clicamos aqui, carregamos a imagem que queremos que seja usada para o conjunto de ícones. Nós baixamos. Dentro da pasta Downloads, agora temos esse favicon_io. Está em arquivo. Agora eu vou extrair tudo para uma pasta. Esse é o conjunto de ícones que eu eventualmente tenho. Não vamos usar tudo isso. Vamos reutilizar aqueles que já estão presentes na pasta pública. Eu só vou abrir essa pasta pública aqui. Em vez do logo192 do React, vou usar apenas o que tenho aqui. Eu copio isso. Eu mudo o nome. Eu excluo o anterior. Eu renomeio este. Então, o mesmo farei com este logotipo. Eu o excluo. Eu movo aquele aqui do mesmo tamanho. Eu lhe dou o mesmo nome. O Favicon será completamente substituído. É isso. Tudo está pronto agora. Se formos para manifest.json, aqui fazemos referência a todos esses ícones. Esses ícones serão usados quando seu aplicativo estiver sendo instalado na tela inicial. O que quer que você especifique aqui, esse arquivo de manifesto instruirá Progressive Web App a usar essas informações. Por exemplo, se aqui especificarmos o aplicativo React como um nome curto, isso é o que os usuários verão quando adicionarem seu aplicativo na tela inicial. Não temos um nome longo para nosso aplicativo. Vamos usar Box Office nome abreviado e Box Office para nome normal. Os ícones permanecem aqui, mas se voltarmos ao nosso aplicativo e nos lembrarmos nossa corrida anterior para o Lighthouse, tivemos esse problema com o ícone mascarável. Vamos ver mais uma vez o que exatamente tínhamos lá. Novamente, eu executo o Lighthouse outdate. Demora alguns segundos aqui. Vamos até o final e vemos que nosso aplicativo pode ser instalado. Está tudo bem, mas não temos um ícone mascarável. Nós vamos aqui. Você leu sobre ícones mascaráveis aqui. Esse é um novo formato. Basicamente, precisamos apenas adicionar outro ícone ao manifest.json e especificar que ele terá a finalidade de ícone mascarável. Podemos usar esse editor Maskable.app para converter um ícone existente em um ícone mascarável. Talvez vamos fazer isso rapidamente. No canto direito, clico no botão Carregar, especifico nosso ícone. Agora, parece assim, mas eu queria ter, digamos, um fundo branco, para que nosso ícone mascarável ficasse assim. Legal. Este será nosso ícone mascarável. Isso resolverá nosso problema com esta lista de verificação no Lighthouse. Clicamos em Exportar. Digamos que será o tamanho máximo. Nós baixamos. Mostrar na pasta. Este será um ícone mascarável que vamos colocar na pasta pública. Eu o movo para cá e agora precisamos especificar esse ícone mascarável. Este está dentro do meu manifest.json e diga que maskable_icon.png, os nomes devem corresponder, será do tipo, deixe-me ver. Onde está? Onde estão essas informações sobre ícones mascaráveis? Aqui. Ele terá um propósito mascarável. Voltamos aqui, especificamos um propósito mascarável. Nós economizamos. É isso. Agora nosso aplicativo ficará incrivelmente bom em qualquer lugar, com nossos próprios títulos, com nossos próprios ícones. Vamos implantar tudo novamente. Espere, desculpe-me. Eu segui o caminho errado. Eu queria implantar tudo no início. Npm run deploy. Agora, vamos esperar alguns minutos e nos vemos assim que o aplicativo for implantado. O aplicativo foi implantado com sucesso. Vamos voltar ao aplicativo e ver o resultado final. Antes de fazer isso, antes de atualizarmos a página, vamos limpar o armazenamento novamente para limpar todos os caches, tudo o que salvamos dentro do navegador, esvaziar o cache e atualizar. Agora, você pode ver que temos nosso ícone personalizado aqui, títulos personalizados. Tudo agora é usado conforme especificamos dentro do arquivo de manifesto. Na verdade, você pode clicar na guia do aplicativo aqui no Manifesto e ver informações diferentes sobre sua inscrição. Agora, vamos ver como ficará quando for adicionado à tela inicial. Em um dos vídeos anteriores, quando adicionamos um dos funcionários do serviço, quando o registramos, adicionamos nosso aplicativo à tela inicial. No entanto, você pode ver que não foi atualizado aqui. Na verdade, vamos executá-lo e primeiro, vamos desinstalá-lo e instalá-lo novamente. O que eu vou fazer é clicar em três pontos aqui. Clique em Desinstalar Create React App Sample. Verifique a marca. Também limpe os dados do Chrome. Agora desapareceu. Voltarei ao meu aplicativo dentro do navegador e o instalarei mais uma vez. Instale o Box Office. Instalar. Agora, boom. Eu volto para minha tela inicial novamente, no meu caso é desktop. Agora eu tenho meu aplicativo Box Office, que se parece com qualquer outro aplicativo no meu computador. Se eu clicar nele, ainda teremos tudo igual. Eu diria que é isso. Agora vocês criam esse aplicativo incrível que funciona offline, que é instalável, que funciona com os diferentes dados dinâmicos das APIs. Você aprendeu muitos conceitos. Eu diria que você aumentou significativamente seu conhecimento sobre React com este, mas agora é isso. Mas antes de terminarmos este, vamos realmente confirmar todos os nossos ícones que adicionamos. Vou adicionar tudo ao palco. Eu vou cometer tudo. Digamos que adicionou ícones personalizados e atualizou o manifest.json. Vamos enviar tudo para a ramificação master para que as alterações sejam refletidas no repositório do GitHub. É isso. Parabéns por isso. No próximo vídeo, vamos resumir exatamente o que aprendemos com a bilheteria. Te vejo lá. 92. 36 resumo: Ei, sim. Neste vídeo, vamos resumir tudo o que aprendemos até agora no Box Office. Agora temos esse incrível aplicativo web progressivo, que funciona offline, que é instalável, que funciona com API, e parece muito legal, não é? Talvez vejamos nosso histórico de confirmações e examinemos isso rapidamente. Em primeiro lugar, como uma ferramenta, digamos, como um padrão para criar bilheteria, usamos o Create React App, que usa a configuração subjacente do web pack, que consumimos usando o pacote react-scripts. Agora você sabe o que são react-scripts. Agora você sabe o que é o Create React App, o que significa que você sabe como trabalhar com o Create React Boilerplate. Também usamos Prettier e ESLint, mas isso não é algo novo. Você já conhece essas ferramentas. Vamos ver. Aprendemos sobre o React Router porque, como você sabe, por padrão e pelo react, não temos nenhuma solução embutida para roteamento dentro de nosso aplicativo. O React tem tudo a ver com renderização, mas não se trata de uma navegação tão simples assim. É por isso que usamos uma biblioteca chamada React Router para obter navegação dentro de nosso aplicativo. Vamos ver. Depois do React Router, adicionamos funções diferentes para trabalhar com dados dinâmicos, para trabalhar com API. Usamos uma API de navegador embutida chamada “Fetch”. Para buscar dados da API, chamada “Fetch”. Para buscar dados da API, criamos muitas funções reutilizáveis que usamos em nosso aplicativo, e elas parecem muito simples. Lidamos com todos os possíveis adicionadores dentro dos componentes, caso algo dê errado, lidamos com os erros adequadamente usando blocos try-catch dentro de nossos componentes. Também soubemos que, se quisermos buscar dados quando o componente é montado, quando fazemos algumas interações na página, em vez de usar “useEffect”, podemos usar uma biblioteca de busca de dados. No nosso caso, conhecemos a biblioteca React Query, que nos ajuda a consultar dados quando o componente montado ou quando realizamos pesquisas na página. Agora você sabe sobre bibliotecas de busca de dados. Bibliotecas de busca de dados são uma ótima opção em aplicativos React modernos. Há uma maneira recomendada de trabalhar com dados porque, à medida que seu aplicativo cresce, você terá mais e mais requisitos. As bibliotecas de busca de dados nos ajudarão a gerenciar tudo isso com facilidade. Agora que também mencionei “useEffect”, agora você sabe o que “useEffect” faz, “useEffect” nos permite executar alguma função de efeito colateral Quando algo dentro do componente muda, temos uma matriz de dependências dentro de useEffect. Deixe-me encontrá-lo aqui no código. Temos uma série de dependências aqui, e quando algo dentro da taxa muda, se o valor muda, executamos essa função de efeito colateral. Sem falar que também criamos nossos próprios ganchos personalizados em cima de “useState”, “useReducer” e “useEffect”. Esses ganchos personalizados são justos, como qualquer outro gancho, mas com lógica extra. Agora você sabe que, caso precise criar uma lógica reutilizável para ganchos integrados, basta criar um gancho personalizado e colocar toda a lógica dentro. Eventualmente, ele se torna reutilizável. Também trabalhamos com armazenamento de navegadores, trabalhamos com armazenamento de sessão, trabalharemos com armazenamento local. Você sabe que agora você pode manter os dados dentro do navegador. Obviamente, isso não substitui um banco de dados. Mas se você precisar reter informações de alguma forma , como a entrada de pesquisa ou as preferências do usuário, poderá usar esse armazenamento perfeitamente. Vamos ver o que mais temos aqui? Vamos voltar ao histórico de confirmações. Aqui também criamos essas páginas dinâmicas. Isso também faz parte do React Router, mas agora você conhece o conceito de páginas dinâmicas. Você cria um modelo ou um esqueleto e, em seguida, pega o parâmetro dinâmico do URL, no nosso caso, era show ID, então, se eu procuro algum programa, vou para mostrar a página dentro do URL, temos o ID de exibição que pegamos dentro do componente e, em seguida, usamos esse ID de exibição para buscar dados. Dessa forma, podemos obter páginas dinâmicas. Agora você conhece esse conceito. Vamos ver o que também temos aqui? Novamente, “UseQuery” sobre dados de consulta, lógica inicial diferente com ganchos personalizados, isso é o que discutimos, também instalamos componentes estilizados. Uma solução de tempo de execução de CSS e JS para componentes de estilo. Agora você pode decidir o que é melhor para você. Use componentes estilizados ou algo muito semelhante ou use a forma tradicional com arquivos CSS. Porque agora você conhece as desvantagens, agora sabe quais são as vantagens e é você quem decidirá o que vai usar. Pessoalmente, prefiro a forma tradicional de estilizar aplicativos e não sou muito fã de CSS e JS. Além disso, adicionamos essa animação de desvanecimento como um substituto para o pacote que mencionei, React-fade-in. Eu mencionei isso apenas uma vez, mas não coloquei muita ênfase nisso. Precisamos de menos dependências em nossos aplicativos. Menos dependências, melhor, porque você precisa gerenciar menos coisas. Acho que faz sentido, e você seguirá essa regra no futuro, porque será para seu próprio bem. Também conhecemos aplicativos web progressivos. O que é o Progressive Web App? É apenas um aplicativo da web que segue lista específica de itens. Por exemplo, você precisa ter um arquivo de service worker, ele precisa ser servido por HTTPS, precisa ter esse arquivo de manifesto e, quando o aplicativo, o site, atende a todos esses requisitos, ele se torna um aplicativo Web progressivo. É como um site intitulado e o título é Progressive Web App. O aplicativo ficou disponível off-line por causa do service worker. Agora você sabe que o service worker é um script executado em algum lugar dentro do navegador, fora dos contextos de nossos aplicativos, e ele encaminha todas as solicitações, todas as solicitações enviadas e faz algo com elas. Em nosso caso, usamos o service worker para armazenar em cache toda a solicitação de saída. O aplicativo funcionará offline depois instalado em algum lugar na tela inicial. No final, adicionamos nossos próprios ícones personalizados usando o [inaudível] que eu gerei e compartilhei com você, mas isso realmente não importa, você pode usar qualquer gerador, mas agora você pode ver o fluxo completo, como o aplicativo está sendo construído do zero até a implantação, estilo e fazendo algumas modificações no futuro. Algo parecido. Parabéns, você fez um trabalho muito bom. Por enquanto, é isso. Te vejo na próxima. 93. O que é base de firebase?: Ei, bem-vindo à nova seção aqui. Vamos falar sobre a solução de volta para o nosso projeto final. Sempre que criamos um aplicativo de página única para nos comunicarmos com o banco de dados, nós normalmente criaríamos nosso próprio servidor AP I ou usaríamos um existente. modernas, Aplicaçõesmodernas, pequenas ou médias não necessariamente para trás e de ossos nus por conta própria a maior parte do tempo que fazem, mas depende do tipo de aplicação. Não seria bom se tivéssemos algum tipo de camada de obstrução nos fundos? E então não precisamos configurá-lo nós mesmos e nos concentrar mais no aplicativo? Bem, base de fogo pode ajudar-nos a conseguir isso. Ele é acenado como solução de serviço que nos dá a camada de abstração em torno de trás e e ele faz. Ainda mais Firebase é Emma Bile e Web Platform, que é construído sobre o Google Cloud Platform. Isso significa que ele pode ser usado junto com qualquer serviço de nuvem do Google. A partir de agora, não precisamos nos preocupar em criar nosso próprio arquivo de manutenção de banco de dados AP I hospedando tudo já está lá e esperando por nós. Então, em nosso código, em vez de enviar um pedido para um A P I para recuperar dados. Nós apenas usar uma biblioteca que tem funções já muito bem para nós. Como obter este documento por I t. E esta função irá interagir com o banco de dados. Ele tem realmente tempo cantar apoio e consultas mais rápidas. E também está bem documentado, o que é realmente importante para entender. O Bachir. Que base de fogo está no próximo vídeo, mas vai passar por serviços de base de fogo e vamos tentar avaliá-los. Vejo você lá. 94. Visão geral do Firebase: Ei, vamos explorar rapidamente a Base de Fogo e seus serviços. Para este vídeo, eu abri fogo baseado Dashboard fora do nosso projeto final Aqui. Podemos monitorar e gerenciar todos os serviços que usamos dentro de um projeto firebase. Poderíamos gerenciar vários APS. Pode haver vários APs de volta, e que irá compartilhar o mesmo banco de dados. Ou se tivéssemos aplicativos Android, IOS e Web, poderíamos gerenciar todos eles a partir de um único painel à esquerda. Dentro da barra lateral. Em desenvolvimento, você pode ver uma lista fora dos serviços principais do Firebase. Vamos um por um. Uma sindicação. Com o serviço, somos capazes de fazer login e autenticar usuários em todos os nossos aplicativos. Isso é muito legal porque, digamos que se olharmos com o Google no site e mais tarde, olhamos para o aplicativo android com a mesma conta, os dados serão os mesmos. Existem muitos sinais e métodos diferentes disponíveis para nós, e a coisa é que todos eles são configuráveis. Foram apenas alguns cliques. Este serviço está completo. Ele tem construído em um sistema de e-mail que lida com todas as verificações de e-mail e recesso. Precisamos que você apenas personalize o modelo fora do e-mail. Além disso, suporta a verificação SMS, o que também é muito legal. Depois vai a base de dados. Firebase tem a base de dados pediu agora loja fogo e banco de dados de tempo riel. Ambos são baseados em Jason nenhum banco de dados sequela com suporte para atualizações em tempo real. Qual é a diferença e qual usar? Depende de muitos fatores, mas aqui estão três diferenças-chave. Primeiro, modelo de preços Loja Fire é cobrado por operação. Leia, escreva, exclua ou atualize. Isso não é bom para gravações de dados de alta freqüência Banco de dados em tempo real tem mais adequado para isso , pois é cobrado para armazenamento e largura de banda, que é o caso de uso perfeito para algo como um aplicativo filho. Segundas consultas. Fire Story nos dá consultas mais avançadas e compostas em comparação com banco de dados em tempo real Assim base de dados em tempo real tem realmente pobre construtor de consultas, mas é bom o suficiente para gerenciar não estruturas de banco de dados complicadas. Terceira estrutura ambos são Jason baseado Fire Store tem documentos, coleções e sub coleções, que tornam o banco de dados mais robusto. base de dados em tempo real é apenas um grande objeto Jason. É por isso que tem peculiaridade muito apoio e na maioria das vezes precisamos de normalizar um k um dados duplicados para o nosso projeto. Vamos usar banco de dados em tempo real porque teremos um monte de Faried e operações de gravação. E nós não exigimos consultas complexas. Se não fosse um aplicativo de bate-papo, Eu teria pico loja Fire como ele tem consultas mais sofisticadas e estrutura de base de dados . Além disso, não estamos limitados a usar em Lee um banco de dados. Podemos combinar tanto armazenamento de fogo e base de dados em tempo real em um único aplicativo. Então temos armazenamento. Nada muito especial. Por aqui. Aqui bolha Porter, imagens do usuário e arquivos de áudio Firebase hospedagem aqui. Vamos implantar nosso site. Ele só suporta arquivos estáticos. Então, se tivermos um aplicativo de renderização do lado do servidor, esta hospedagem não funcionará. As funções de nuvem em nosso aplicativo também foram capazes de escrever personalizado de volta e informar fora do servidor últimas funções de nuvem que podem ser chamadas de dentro do casaco. Vamos implantar apenas um que enviará notificações aos usuários. Vamos falar mais sobre servidor última quando vamos entrar na máquina tópico. Lauren, obter ferramenta incrível que fornece utilitários de aprendizado de máquina, como reconhecimento de imagem e os outros. Mas, infelizmente, ele só está disponível para IOS e Android APS na parte inferior. Temos outros serviços. Todos eles são complementares e usados para monitorar e analisar aplicativos implantados. Podemos gerenciar o desempenho fora do nosso site, quão rápido ele baixa e algumas outras métricas. Podemos até integrar o Firebase Analytics, que é basicamente o Google Analytics, mas embrulhado como um serviço firebase e, no fundo restringimos serviços para envolver os usuários em nosso projeto. Usaremos apenas mensagens na nuvem firebase que nos permitirá enviar notificações em tempo real para os usuários se o navegador tiver suporte para ele. E é basicamente isso. Esta foi visão geral de alto nível fora da lareira. Mas e a segurança? É seguro o suficiente? Vamos descobrir que na próxima mídia vê-lo lá. 95. Segurança de Firebase: Ei, vamos ver se a Firebase está segura. Já que não temos nenhum código do lado do servidor, vamos acessar o banco de dados do lado do cliente. Como vamos expor dados confidenciais? Sim e não. Na lareira bancos de dados são acessados via Euro Público. Isto faz parte do conflito. Digamos que temos alguns dados dentro do banco de dados. Temos público o seu el No. Um também. E se a Pessoa Aleatória tentar acessar o Ural e não protegemos o banco de dados, essa pessoa pode obter todos os dados, quer sejam públicos ou não, para evitar acesso não autorizado, suas regras de segurança. Essas regras definem como os dados podem ser acessados e por quem. Isso significa que o nível de segurança depende de como as boas regras de segurança são escritas. É uma boa prática olhar para baixo o banco de dados por padrão e, em seguida, ele apenas regras. À medida que escrevemos regras de segurança de código aplicam-se a Lee aos seus clientes. I Se escrevermos backend personalizado com funções de nuvem, essas regras não se aplicarão quando o aplicativo crescer. Algumas pessoas acham difícil escrever rituais de busca. Por esse motivo, eles usam funções de nuvem e executam servidores na validação. O mesmo se aplica ao armazenamento em nuvem. Temos público que estão doentes e regras por padrão. armazenamento só pode ser acessado por usuários conectados. Para a maioria dos casos, funciona bem. Mas isso não significa que se carregarmos uma imagem que queremos compartilhar, essa imagem será bloqueada. Todos os ficheiros enviados podem ter a Europa pública. Tudo bem, é isso por segurança. Espero que tenha sido abrangente e conciso. Agora, que tal preços? Firebase é livre? Vou descobrir isso no próximo vídeo. Vejo você lá. 96. Preço do Firebase: Vamos ver se precisamos pagar algo para usar a base de fogo. Quanto a fora, existem duas plantas disponíveis. Faísca e Blaze plano desencadeado é completamente gratuito e vem com algumas limitações. O plano da polícia é modelo de pagamento conforme você vai. Ambos têm muito generais freakier E mesmo se você está inscrito para Blaze plano a menos que o seu APP tem um monte de usuários ativos, você não vai pagar nada para nós para ter certeza de que não vai ser cobrado plano faísca está bem. No entanto, com as atualizações recentes da sua base de fogo e do Google Cloud para usar as funções da nuvem , precisamos ter o plano Blaze ativado para o nosso projeto. Mas não se preocupe, mas vamos entrar nisso quando começarmos com as funções da nuvem. Até então, plano acionado é a nossa escolha Para obter mais detalhes, navegue até a página de preços para Avala tudo você mesmo. Tudo bem, acho que é tudo o que eu queria cobrir para a base de fogo na produção. No próximo vídeo, vamos finalista começou a construir nosso projeto. Vejo você lá 97. Visão geral do projeto: Bem-vindos à nova seção. Você fez uma pausa? Porque neste momento vou mostrar-vos como será o nosso projecto final quando entrarmos no website pela primeira vez . Mas veremos o sinal na página. Daqui. Podemos continuar com Facebook ou Google. Vamos escolher o Google. Então eu vou escolher por segunda conta e, em seguida, eu estou dentro do aplicativo. Então, à esquerda, eu posso ver esse quadro criar novos fundos de sala de bate-papo e listar as salas de bate-papo disponíveis à direita . Se eu clicar em qualquer uma das salas de chat, eu vou ver suas mensagens e algumas outras coisas que vamos cobrir apenas em um segundo. Vamos primeiro começar com o painel, então se eu clicar nele a partir daqui, eu posso gerenciar minha conta. Então, no topo, eu posso ver que agora eu estou conectado ao Google, e eu também posso associar minha conta ao Facebook. Então, se eu clicar em um link para o Facebook, ele irá me solicitar minhas credenciais de phrasebook, se necessário. E agora estou ligado ao livro de frases. Isso significa que na próxima vez que eu vou olhar com o Facebook para comprar aplicativo, eu vou ser vinculado a esta conta. Eu vou acabar com a mesma conta, então eu tenho um apelido e eu posso editar a partir daqui. Então, se eu clicar no botão editar, eu serei capaz de alterá-lo. Então vamos alterá-lo um pouco, e se eu clicar seguro, ele será atualizado. Além disso, eu posso editar o meu ómetro se eu clicar em Selecionar Novo Avatar, e se eu escolher esta imagem, Eu vou ser capaz de adicioná-lo um pouco em desenvolver estado. E então eu vou clicar em un upload e meu Al Atar será atualizado. E daqui, também posso sair. Em seguida, temos criar novo botão de sala de bate-papo. Então vamos especificar no nome da Europa, vamos dizer whoa e descrição vai ser Whoa! Se eu clicar nele, ele aparecerá aqui, e a sala de bate-papo estará completamente vazia por enquanto. Então vamos selecionar a primeira sala de bate-papo porque ela já está preenchida com algumas mensagens. Então, o que temos aqui? Então, em cada mensagem, se a tivermos nela, podemos ver esse botão. Ele irá mostrar-lhe quantos gosta desta mensagem em particular metade. Então, se eu clicar nele, vou remover o dedo do pé como se eu clicar novamente como será adicionado a esta mensagem. E também podemos ver se este usuário está online ou offline. Então, se a tivermos neste círculo, podemos ver que esse usuário estava off-line neste dia específico, neste momento específico. E esta é a minha conta. É por isso que estou online. Além disso, você teria aqui se clicarmos no apelido de usuário Global Sea Motile janela com o seu de um carro . É nome completo Membro desde esta data. Então, quando este usuário se juntou ao aplicativo e também podemos controlar a permissão de administrador fora deste usuário se estamos atualmente um administrador fora deste grupo, vamos dar uma olhada na permissão de administrador apenas em um momento. Então, o que mais temos? Então todas as mensagens são divididas em datas. Eles são agrupados por datas. Então você pode ver hoje eu enviar esta mensagem é ontem havia essas mensagens e assim um também nós temos paginação fora. Mensagem é que significa que não baixamos todas as nossas mensagens do banco de dados. Quando vemos o bate-papo um carregamento apenas, digamos 15 mensagens. E então, quando clicamos em carregar mais, veremos mais mensagens sendo carregadas para a nossa aplicação. Tudo bem, então nós somos capazes de enviar mensagens de texto normais para o nosso Chade. Então também podemos enviar arquivos. Então, se eu clicar no botão de anexo, eu vou ver este mortal. Então eu clico no upload. Posso selecionar arquivos normais também. Assim coça. Então eu vou selecionar este arquivo, esta imagem, que eu vou abri-lo. Vai aparecer aqui que eu vou clicar, enviar para o chat. E como você pode ver, se eu enviar um arquivo normal, Eu perdoo Carregá-lo apenas clicando sobre este seu fora. Se for uma imagem, ela será exibida aqui. E se eu clicar nele, eu vou ver a visualização. E também, eu vou ter esta vista inferior original. E se eu clicar nele, o original será aberto com o novo toque. Além disso, somos capazes de enviar arquivos de áudio. Então, se eu clicar neste botão aqui, o registro será iniciado e eu posso ver isso eu posso. Aqui, significa que atualmente está gravado no meu microfone. Então, se eu clicar neste botão mais uma vez, ele salvará minha mensagem de ódio. Isso foi gravá-lo agora mesmo. E eu poderei reproduzi-lo se for suportado pelo navegador. Tudo bem, o que temos mais? Então, no topo, podemos ver o nome do quarto, podemos ver a mensagem de transmissão. E este botão azul aqui, eles estão relacionados, mas vamos dar uma olhada em um momento. Nisso, podemos clicar nas informações da sala para ver a descrição desta sala de bate-papo. E também, se nós somos um administrador fora deste grupo, nós somos capazes de ver este Aiken. Então, se clicarmos nele, podemos adicioná-lo. Informações do quarto, como nome e descrição. Então, se eu clicar no botão editar novamente, Eu posso para qualquer nome que eu quiser. E então eu sou capaz de salvá-lo, e ele será atualizado com sucesso. Tudo bem, agora, sobre mensagens transmitidas. O que são esses? Deixe-me mostrar como admitir permissão pode ser controlada. Então, deixe-me realmente olhar para esses aplicativos do meu telefone, e eu vou remover a permissão de administrador. Então agora eu estou dentro do aplicativo, e você pode ver que o status foi alterado. E agora posso ver o verde escuro. Tudo bem, então eu vou remover a permissão de administrador para esta conta que você pode ver agora. Então, o que vou fazer? Vou clicar no meu perfil e vou clicar na sala de Admitir permissão, mas a partir do meu telefone. Então, agora, eu removi a permissão de administração. E agora só posso ter este botão de notificação e informações do quarto. Tudo bem, agora, vou dar permissão para mim mesmo, e você pode ver agora que está atualizado e tudo está em tempo real. Então, o que está acontecendo aqui? Então, primeiro de tudo este botão de notificação, Então, isso significa que eu quero assinar ou cancelar a assinatura de notificações que eu vou receber de admite fora desta sala de bate-papo. Por isso, neste momento, estou inscrito. E se eu mudar de idéia, eu vou estar na assinatura, e eu não vou receber nenhuma mensagem em tudo. Então, o que são essas notificações? Estas são notificações em tempo real que estão sendo exibidas pelo navegador no dispositivo. Portanto, são essas permissões ou notificações que se eu clicar nesta parte inferior, eu posso ver notificações aqui e agora elas são permitidas. Então, o que vai acontecer? Deixe-me enviar uma notificação do meu telefone para todos os usuários dentro desta sala de bate-papo. Então agora, do meu telefone, vou clicar na mensagem de transmissão aqui. Vou especificar o título e a mensagem, e depois vou publicar a mensagem. Então vamos ver o que vai acontecer. Então eu Steidl, Eu vou selecionar, Vamos dizer web surdo e para mensagem, Eu vou digitar Olá do telefone e, em seguida, publicar mensagem. E como você pode ver agora, eu tenho essa web metade desta sala. Eu ajudo a partir do meu telefone. E também tenho esta notificação dentro das janelas. Então o que? Isso significa que se eu estiver atualmente no site, eu vou receber esse tipo de notificação que eu posso fechar se eu digamos fora do navegador ou eu apenas fechar o navegador completamente. E se eu receber uma notificação, deixe-me enviar outra e sim, eu posso ver que eu ainda vou ter notificação dentro de janelas ou dentro de seu sistema operacional se ele é suportado. Então, isso é o que nossas mensagens de tempo riel desta forma você não pode se eu seus usuários para envolvê-los . Então isso é basicamente sobre nossa aplicação, um monte de coisas para cobrir e eu vou torná-lo o mais abrangente possível. Acho que vai gostar. E eu vou te ver no próximo vídeo. Vamos começar. Vejo você lá. 98. As atualizações estão chegando !!: Olá pessoal. Neste vídeo, gostaria de fazer referência às próximas atualizações do aplicativo de bate-papo. Ambos os projetos, Tic-tac-toe e Box Office, foram atualizados, mas as atualizações para aplicativos de bate-papo ainda não foram lançadas. Para tornar a transição das atualizações do Box Office para a versão mais antiga do aplicativo de bate-papo o mais tranquila possível , este vídeo existe. O que vamos fazer é usar o modelo que preparei para nós. Temos esse repositório de aplicativos de bate-papo para iniciantes. O link será compartilhado com você nos recursos, para que você tenha acesso a ele. Você acaba nesta página, você vai para esta página, então o que você precisa fazer, você precisa clicar no botão do código verde, então você clica em “Baixar Zip”. Em seguida, você vai até o local onde baixou o arquivo zip e o descompacta. Acabei de pegar aquela pasta. Eu o coloquei em downloads e aqui estou o projeto. Então eu vou para o VS Code. Eu abro essa pasta como o projeto no VS Code. Aqui, esse e eu vejo isso. Aqui você encontra o projeto inicial. Você tem todas as dependências necessárias instaladas, como compilador Sass, biblioteca rsuite. As diversões são importantes. Em seguida, temos o roteador react e a biblioteca Firebase instalados. ESLint e Prettier estão configurados aqui. Você não precisa se preocupar com isso. Dentro da fonte, você tem estilos aqui. Aplicativo básico com o React Router da versão mais antiga que é usado em vídeos de aplicativos de bate-papo. Você tem tudo configurado, estilos importados, está tudo pronto. A única coisa que você precisa fazer é primeiro inicializar o Git aqui. Você digita git init , adiciona tudo ao stage e confirma isso. Logo depois disso, você precisa associar esse novo projeto Git ao seu repositório do GitHub. Você acessa o repositório do GitHub, cria um novo repositório, obtém a URL do repositório e, em seguida, faz git remote , adiciona a origem e a URL do repositório que você copiará ao criar um novo repositório aqui no GitHub. Logo depois disso, você precisa instalar dependências. Como você pode ver, não há pasta de módulos de nós. A única coisa que você precisa fazer é digitar npm install e ele instalará todas as dependências listadas no pacote Jason. Depois disso, você está pronto. Você precisará usar o script start executando npm run start e continuar com o desenvolvimento. O resto permanece o mesmo. Continue assistindo ao aplicativo Chat e tudo ficará bem. É isso. Nos vemos lá. 99. Scaffolding projeto: Ei, bem-vindo. Agora vamos usar scuffled nossa proteção como antes, vamos usar criar aplicativo reator e para criar em seu projeto, precisamos abrir a pasta de todos para colocar o nosso projeto no terminal. Então, do meu terminal, eu vou executar e p x criar reagir, e então o nome da pasta, que vai ser Chad app. E então eu vou colocar uso NPM porque eu tenho fio instalado no meu sistema. E agora o projeto da UE será criado para nós. Vamos esperar até que tudo esteja feito. Tudo bem? Parece que terminamos. Agora vamos abrir o código V. E daqui, vamos abrir nossa nova pasta. Então, o que temos lá dentro como antes? Sob fonte, temos nossos arquivos iniciais para o pacote Jason. Temos nossos roteiros e assim por diante. Então vamos executar nossa limpeza inicial para que não precisamos de ap CSS. Então também não precisamos de tudo isso dentro do nosso componente de aplicativo. Então vamos limpá-lo como este leva a excluir este nome de classe, vamos colocar apenas Olá. Vamos Tillett logotipo e importação para nós. Sim. Tem arquivado então não precisamos AP Test GS do que quatro CSS índice. Bem, na verdade não precisamos dele também, então para o índice? Sim, vamos remover o modo de rua porque receberemos erros quando usaremos outras bibliotecas. É totalmente normal. Então vamos remover Índice CSS e vamos comentar Service worker por enquanto, assim, então não precisamos de logotipo SVG. Não precisamos de fazer testes e terminamos aqui. Agora, o que fazemos? Vamos instalar outras dependências, e vamos obtê-las a partir da pasta Ativos. Então vamos abrir esta pasta e abrir andaimes. Doug Jason. Então, a partir daqui vamos copiar comentários para instalar dependências. Então vamos copiar a primeira linha e colocá-la dentro do nosso terminal integrado assim . Agora, enquanto ele está instalando, vamos criar preacher e excelentes arquivos de configuração. Então, para excelente, vai ser, sim, sim, terra RC. E para pregador, vai ser mais bonito, RC, e também vamos copiá-los do nosso andaime para o arquivo Jason. Então, para sim, inclinado nós temos aquele. Vamos colocá-lo aqui e salvá-lo. E por ano nós temos essa. Então, sim, fiapos e pregador são Don, vamos ajustar nosso roteiro NPM. Então vamos copiar tudo isso e colocá-lo dentro. Empacote Jason, dentro desta seção de script na parte inferior, exatamente assim. E também temos o script claro para limpar a pasta de contas. Então, logo antes de produzirmos nosso construído vamos correr e PM, Ron Clear como um morto. Tudo bem, então terminamos com os roteiros. O que mais temos dentro do arquivo de desdobramento do disco? Temos outra linha para dependências de instalação, que é notas. Bundas são traje reagir roteador e reator para burros. Vamos copiá-lo. E deixe-me explicar o que vai acontecer. Então, para o nosso sistema de estilo, usaremos o SAS com você. Eu biblioteca nomeados estão aqui, e podemos dar uma olhada no nosso terno se não avaliarmos a sua documentação oficial. Então, o que é uma biblioteca Y? É uma biblioteca que nos dá já bastante encontrar componentes que podemos usar. E é basicamente isso. Veremos que quando começarmos a usá-lo é bastante simples, e isso aumenta nossa velocidade de desenvolvimento. Você vai ver isso. Tudo bem. E sempre que vemos que o nosso terno não é suficiente para os nossos casos vamos usar diz Ok. Além disso, nós instalamos, reagir roteador e reagir Roterdão Tudo bem, então é basicamente isso. Mas uma coisa a fazer é também copiar esta pasta de estilos para o nosso projeto. Então, o que é essa pasta Styles? Então ele vem com Assad fora de classes pré-definidas. Então vamos realmente copiar esta pasta. Então eu vou copiar esta pasta. Então eu vou abrir esse arquivo em ah, revelar no Explorador de Arquivos, depois dentro de feridas. Vou colar esta pasta de estilos e vamos dar uma olhada. O que temos lá dentro? Então nós temos o nosso arquivo principal, que é basicamente o nosso índice CSS ou apenas o nosso arquivo principal para estilos aqui iria definir, digamos, realmente algumas classes off que vamos usar. Ele vai levar você olhar e eles Eles são realmente simples. Nada muito complicado. Em seguida, temos utilitário e você cores facilidade que importamos para Maine CSS. Então agora podemos gerenciar nossos arquivos. Então, para utilitário aqui temos classes que são semelhantes às classes utilitárias bootstrap, então vamos usá-las muito em nosso código. Então, por favor, dê uma olhada neles. Eles não são tão difíceis de gerenciar. Não tenho cores de utilidade. Estas são basicamente classes para cores. Nada muito especial aqui. E então nós temos override como ele SS. Então, este ano eu biblioteca tem certeza de que ele é destinado para aplicativos de desktop. Assim, alguns fora de seus componentes não são realmente bons para exibidos em dispositivos móveis e para ajustá-los para telas móveis. Eu modifiquei um pouco seu CSS Eu substituo suas classes um pouco. Então agora eles ficam bem em dispositivos móveis também. Isto é só para tornar tudo bom. A polícia dá uma olhada em tudo isso. É muito simples. Apenas certifique-se de que você sabe o que está acontecendo. Então, dentro de Abdel Gs, o que precisamos fazer, precisamos importá-lo. Então, vamos importar. Ah, nós somos estilos CSS principal assim. E também precisamos configurar nosso terno e avançar. Então, se navegarmos para seu site oficial e se formos para começar e se clicarmos em uso em Creta, reagir aplicativo a partir daqui, podemos ver que precisamos também importar suas soluções CSS padrão copiar esta linha de código e colocá-lo antes de importar nossos estilos principais assim. Então agora estamos prontos para ir com o nosso conflito por vocês. Uma coisa a fazer aqui é realmente conectar nosso projeto para obter ajuda. Então vamos abrir o terminal integrado e confirmar todos os nossos arquivos. Então, primeiro, vamos adicionar tudo ao estado do palco, e depois vamos nos comprometer. Digamos que andaime algo assim. Agora vamos abrir o Teoh. Vamos arranjar-lhe uma conta. Então vamos criar um repositório. Em seguida, vamos nomear seu aplicativo de bate-papo. Vamos torná-lo privado, e vamos criar um novo repositório Logo depois disso, podemos copiar este comando na parte inferior. Obter controle remoto na origem. Vamos copiar isso e passear no nosso terminal. Agora, nossos arquivos locais serão associados a este repositório remoto e precisamos colocar nossas mudanças locais on-line para obtê-la. Vamos usar a mostarda de origem push. E agora vamos dar uma olhada para que tudo seja implantado. Se atualizarmos a página, nosso projeto estará online. Então temos tudo. Chraidi. E no próximo vídeo vamos começar a construir. Vejo você lá 100. Crie e configure o projeto do Firebase: Ei, neste vídeo, vamos criar um novo projeto firebase e editar em nosso aplicativo. Vamos lá. Então vamos abrir o Google. E aqui vamos digitar base de fogo. Então vamos abrir primeiro o seu L e vamos acabar na base de fogo. Página oficial da Web. Como o Fire Base faz parte da plataforma Google Cloud, o Google gerencia tudo. Isso significa que não precisamos criar uma nova conta ou algo assim. Se tivermos uma conta do Google, o que eu acho que todo mundo tem, então vamos associar nossa conta do Google ao Firebase Project. Então, vamos clicar em Get Started e aqui nós clicamos em Add New Project. Em seguida, vamos especificar o novo nome do projeto, que vai ser chat Web app. Digamos que, em seguida, vamos clicar em Continuar. Então vamos desativar o Google Analytics. Na verdade, não precisamos dele. E vamos esperar alguns minutos até que nosso projeto seja criado. Ok, bom. Parece que o projeto está pronto. Vamos continuar. Depois acabamos no painel de instrumentos da base de fogo. Então, a partir daqui, vamos gerenciar tudo. E como você pode ver, estamos atualmente no plano de faísca, então isso significa que não seremos cobrados por nada. Muito bem, agora temos de adicionar a nossa aplicação Web ao nosso projecto firebase. Então, vamos clicar neste botão de configurações e, em seguida, escolher as configurações do projeto. Então, aqui na parte inferior, veremos nosso APS a partir daqui. Vamos clicar neste aplicativo de laboratório, e então vamos inserir o nome para o nosso aplicativo, que vai ser, digamos, apenas conversar e não vamos configurar a hospedagem firebase. Vamos clicar em Registrar. Também levará alguns segundos, e agora nossa aplicação está pronta. Vamos clicar em, Continuar a aconselhar. Agora precisamos configurar serviços que usaremos dentro de nosso aplicativo. Então, primeiro, vamos configurar o banco de dados. Então, vamos clicar nele. E nesta página, somos capazes de configurar a Cloud Fire Store ou a base de dados em tempo real, por isso certifique-se de que você não usa a nuvem Fire Store. Você usa um banco de dados em tempo real aqui na parte inferior, então vamos clicar, criar banco de dados e vamos selecionar start no modo bloqueado para que todas as nossas regras sejam olhadas para baixo. OK, então vamos habilitá-lo, e vai levar alguns segundos apenas para criar um novo banco de dados para nós. Tudo bem, está feito. Agora precisamos também configurar o armazenamento para o nosso aplicativo. Então, vamos clicar nele e começar. Vai pedir-nos regras. Vamos clicar em seguida. Então precisamos selecionar o local para o nosso armazenamento. É muito importante e realmente influencia essa velocidade, então basta selecionar o mais próximo de você. Para mim, é algo, penso eu, com a Europa. Então eu escolho a Europa Oeste três. Então eu clico em Dung e vai levar alguns segundos para criar uma nova história para nós. Vamos esperar. Está bem, Perfeito. Parece que o depósito está pronto. Nossa última coisa é configurar a autenticação para o nosso aplicativo. Então, vamos clicar em autenticação aqui. Não temos usuários cadastrados. Por enquanto, vamos clicar em Sign and Method, e a partir daqui podemos ver todos os provedores de assinatura que podemos usar. Não usaremos e-mail, e a senha usará apenas o Google e o Facebook. Então, primeiro, vamos clicar nele. E, em seguida, vamos apenas clicar em habilitar assim. Então vamos selecionar suporte e e-mail e, em seguida, projetar o nome público enfrentando. Vamos talvez disse algo como bate-papo, aplicativo e vamos clicar seguro, e depois que ele vai configurar tudo automaticamente. Não precisamos nos preocupar com nada. O Google Sinan já está ativado. E agora o Facebook? Faça login Então, vamos clicar nele. E a partir daqui não teremos nenhuma configuração automática. Precisamos fazer isso manualmente. Então, vamos clicar em ativar aqui. Precisamos preencher APP, idéia app segredo. E precisamos usar isso. Redirecionar seu l Então, o que precisamos fazer dentro do Google? Precisamos digitar Facebook desenvolvedor. Então vamos ao Facebook para desenvolvedores. E aqui nesta página na parte superior, vamos clicar no meu APS e a partir daqui vamos clicar em Criar APP, permite selecionado. E este nome da peça vai ser algo como gráficos apenas tiro chorou. Tudo bem, então vamos clicar em Criar aplicativo I d. Em seguida, vamos executar verificação de segurança enviado e ah foram aplicativo Facebook será criado. Então, a partir daqui o que precisamos fazer precisamos ir para as configurações, em seguida, ir para o básico E aqui vamos encontrar o nosso aplicativo I d e up segredo. Vamos chamar p app I d e, em seguida, acelerá-lo aqui. Então precisamos também obter o segredo do nosso aplicativo. Vamos clicar no show e vamos chamá-lo também e colá-lo aqui dentro da base de fogo. E também precisamos adicionar isso. Redirecione seu l aqui, vamos copiá-lo. Então vamos salvar nossas alterações. E aqui em Prokes, vamos clicar em sinal mais. Então, quando clicamos nele, precisamos selecionar o Facebook. Olhe e vamos clicar em Configurar. E, em seguida, precisamos selecionar que poderemos fazer login na Web, em seguida, site seu l. Eu não sei. Coloque algo que realmente não importa. Na verdade, não, não precisamos disso. Vamos clicar nas configurações porque já temos Facebook. Logan nisso Foi apenas um começo rápido da equipe do Facebook. Então aqui para estes redirecionamento válido o seu mais precisamos adicionar este seu l que temos na base de fogo . Então, certifique-se de que está aqui. Então agora é editar. Vamos clicar em salvar as alterações. E agora a nossa aplicação no Facebook está pronta. Então, vamos salvá-lo. E agora o nosso Facebook em configurá-lo e nós configurá-lo tudo dentro do site firebase . Agora podemos realmente adicioná-lo ao nosso código. Então vamos voltar ao código V e a partir daqui. Vamos abrir o nosso terminal primeiro. Acho que precisamos de instalar o Global Seelye da base de fogo. Então, para isso, vamos digitar NPM instalar ferramentas firebase Dash G e instalá-lo. Já o tenho na minha máquina, por isso não vou instalá-lo duas vezes depois disso. Quando temos essas ferramentas de base de fogo, precisamos digitar base de fogo nele e isso é tudo. Depois disso, ele irá solicitá-lo. Autorize-se, por favor, preencha as instruções. E depois disso, quando eu executar este comando, eu verei esta luz no trabalho. Então, estou pronto para prosseguir. Sim. Então eu preciso selecionar os serviços que eu quero inicializar. Então eu preciso apenas de banco de dados. Então eu navego com setas e eu seleciono com espaço e também eu preciso de hospedagem Onley. Aqueles dois não selecionam armazenamento. Então, eu apertei Enter Então eu vou escolher usar um projeto existente e, em seguida, eu vou selecionar chat Web app que eu acabei de criar. Eu selecionei qual arquivo deve ser usado para rolos de resíduos posteriores. Vamos pressionar apenas enter do que o diretório público que eu quero usar em vez de público. Vamos digitar construído e, em seguida, eu quero configurar meu aplicativo como um aplicativo de página única. Isso é verdade. Então, vamos clicar. Sim, e o HTML de índice construído já existe, certo? Sim. Eu quero que você anule. Tudo bem agora. A base de fogo é associativa. Digamos que o nosso projeto remoto que acabamos de criar que um associado com o nosso projeto local podemos ver Firebase Jason Fire Besar See que contém o nosso projeto I d do que dentro das regras de banco de dados. Temos nossas regras de banco de dados e dentro da base de fogo Jason, temos nossa descrição do projeto. Assim, para regras de banco de dados são implantados a partir desse arquivo para hospedagem, temos pasta pública, que é construído. Então temos ignorar arquivos que não vamos implantar para o firebase hospedagem e também reescreve. Lembra quando tentamos carregar nosso projeto no hip hop? Então, quando atualizamos a página, não fomos encontrados. Então, isso é porque temos aplicativo de página única e Firebase resolve esse problema apenas escrevendo todas as rotas e configurá-lo para rap de página única. Por isso, não teremos quaisquer problemas com isso. Tudo bem, então é isso. Agora podemos realmente instalar biblioteca em nosso projeto. Então, para isso, vamos apenas digitar PM instalar firebase. E vamos esperar até que esteja feito. Muito bem, temos a base instalada como uma biblioteca. Agora o que precisamos fazer sob pasta de código-fonte vamos criar em sua pasta que vamos nomear MISC e aqui vamos criar um novo arquivo firebase dot gs. Aqui vamos configurar nossa base de fogo dentro do nosso aplicativo. Então primeiro acho que precisamos fazer precisamos voltar para o site, em seguida, novamente voltar para as configurações do projeto. E se descermos daqui, podemos encontrar esse conflito da base de fogo. Então vamos copiar isso. E aqui vamos criar um novo e valioso, digamos, conflito constante e vamos colá-lo assim, agora capaz. Importar também bibliotecas do firebase. Então vamos digitar base de importação de fogo do aplicativo Firebase. É importante não importar do firebase porque ele irá importar toda a biblioteca e toda a biblioteca é realmente, muito grande, realmente, muito grande, e irá adicionar todos os arquivos a partir dele. Então nós nos certificamos de que só importou aplicativo firebase que o que precisamos fazer precisamos chamar fogo base dar inicializar aplicativo e dentro Precisamos votar nosso arquivo de conflito Então vamos colocar vir grosso. E agora isso para inicializar aplicativo retorna como uma instância fora do fogo aplicativo baseado. Então vamos colocá-lo em um valioso vamos atribuí-lo a, digamos, apenas um aplicativo assim. E estamos prontos para ir agora. Usando este aplicativo valioso, estamos prontos para acessar serviços firebase como up off ab abelhas nativas, função de loja de fogo, mensagens de tudo isso. Então, mas isso é o que faremos no próximo vídeo para como somos feitos. A única coisa que eu quero fazer antes de terminarmos este vídeo, eu quero comprometer nossas mudanças para obter ajuda. Então vamos esquecer no ponto, então vamos colocar, obter commit e vamos dizer que o projeto inicializado da base de fogo algo assim. Tudo bem, Perfeito. Vejo-te no próximo. 101. Criando rotas particulares e públicas: Ei, agora temos a base inicializada dentro do nosso projeto. Vamos começar a construir o projeto em si. A primeira coisa que eu vou fazer eu vou abrir meu terminal e eu vou executar e PM Run começar a começar a desenvolver servidor. Mas logo antes de executar este comentário, eu vou criar um novo arquivo, que é dot e n v dot local e eu vou colocá-lo no diretório raiz e aqui rivais pacificar navegador para nenhum. Isto é para evitar e PM Ron começar a iniciar o aplicativo instantaneamente dentro do meu navegador. Então eu realmente odeio esse comportamento. Se você gosta, não faça este navegador. Nenhuma coisa. Então agora eu vou executar este comando e eu preciso ir manualmente para o navegador e acessar o host local 3000. Então aqui eu vou ver a mensagem Olá que eu especifiquei dentro de Abdel Gs quando o risco se desdobrou o projeto. Agora o que precisamos fazer precisamos definir nossas páginas no início. Mas nós não inicializamos reagir rotor quando o risco se desdobrou o aplicativo então vamos navegar para togs índice e aqui para inicializar reator importará rotor navegador de reagir roteador burro e em seguida, precisamos envolver o nosso componente aplicativo em torno do navegador, componente rotativo. E agora somos capazes de usá-lo. Ok, bom. Vamos lá. Teoh Abdel Gs e ouvir quais rotas vamos definir. Vamos primeiro usar o interruptor em vez disso. Fora disso, Def. Então eu vou colocar interruptor de reagir mais rudes do que dentro do interruptor. As pessoas definem rota. E que rotas devemos colocar aqui? Bem, teremos algumas rotas para encontrar, e uma delas está assinando a página e a página inicial. E a coisa é que não seremos capazes de acessar a página inicial até que estejamos conectados ao APP. Então precisamos definir algum tipo de truta privada que só pode ser acessada se estivermos assinados . Então, o que vamos fazer a primeira coisa que as pessoas fazem isso irá criar uma nova pasta nas páginas de nomes acessíveis ao recurso. Aqui vamos criar dois novos componentes e que representarão nossas páginas. Primeiro vai ser um sinal na página e ela está aqui. Eu vou andaime e você componente com a extensão snipper. E vamos apenas assinar assim. Então eu vou criar outro componente, Holmdel Gs e eu vou fazer exatamente a mesma coisa. E eu vou nomear uma casa justa agora Como podemos definir essas linhas aqui? Podemos colocar rota e, em seguida, podemos colocar primeiro sinal em modo que esta rota é definida. Mas e quanto a casa? Como podemos torná-lo privado para isso irá criar outro componente. Vamos nomeá-lo rota privada e ele vai imitar este componente rota que vem de reagir Router. Mas será melhorado e verificará contra alguma condição. Então, sob feridas, vamos criar novos componentes de pasta Aqui vamos colocar uma nova rota privada de arquivo assim. Então ele irá imitar este componente de rota. Então, como é pacificar este componente de rota? Que problemas nós traçamos? O que as crianças fazem um caminho. Então precisamos especificar caminho. Então, para assinar, será só assinar. Agora, sobre o soldado Rauer. Então vamos definir como vamos usá-lo. Então vai ser uma rota privada para dentro. Precisamos derramar um componente ou apenas Crianças que queremos renderizar. Vai ser a nossa página inicial assim e para adereços. Precisamos também especificar que vamos renderizar este componente em apenas barra. Ok, agora dentro da rota privada. Sabemos que o que quer que passemos para este componente privado viajado como um adereço será realmente tipo de redirecionado para este componente de rota. Então aqui vamos estruturar tudo e colocá-lo dentro. Digamos que adereços de rota. A única coisa adequada que precisamos para obter é as Crianças reais que queremos renderizar. Então vamos d estrutura Crianças e tudo o resto estará disponível sob adereços de rota. E precisamos derramar uma condição simples aqui. Digamos que por enquanto. Já que não temos nenhum perfil, vamos criar o touro inestimável. Digamos que o perfil seja falso. E agora o que vamos fazer, vamos perguntar se o nosso perfil está definido como tolos. Se não temos nenhum perfil, então nós vamos retornar e você componente que não usamos antes que ele vai ser redirecionada , que também vem de pacote de rotor reagir. E este redirecionamento será basicamente redirecionado para especificar passagem. Portanto, ele recebe apenas um adereço, que é para e para isso irá especificar. Então, se não tivermos sinais e dados. Se não tivermos um perfil, vamos redirecionar para a assinatura. Tudo bem. Bastante simples. Agora, se esta condição não ocorrer, então nós normalmente usaríamos nosso componente que passamos como Crianças. Então, em vez de retornar este def, vamos simplesmente retornar rota de reagir rotor de quatro adereços. Vamos especificar todos os adereços que o recolheremos daqui. Então vamos espalhá-los sobre este componente de rota com apenas esta sintaxe e dentro crianças verbais assim. E se a guardarmos, vamos verificar. Se ele realmente funcionou agora, se eu vou tentar acessar barra uma página inicial barra, Eu vou ser instantaneamente redirecionado porque nós sempre temos condição falsa. Então isso significa que sempre seremos redirecionados para a página de login. Então, se eu disse que é muito verdade agora se eu vou tentar acessar home page, eu estarei lá. Então é isso. É assim que podemos fazer a rota privada. Além disso, quando tivermos sessão iniciada, não queremos ver a página de início de sessão. Queremos ser redirecionados também para, digamos, para o nosso painel ou para a página inicial. Então, o que podemos fazer, vamos criar outro componente que vamos nomear público público. Então vamos criar uma rota pública. Não Sim, e vamos realmente copiar tudo da rota privada. E aqui, vamos renomear rota privada para rota pública. E aqui a coisa será a próxima. Então, se temos perfil, então vamos ser redirecionados para a página inicial. Desta forma, se estivermos conectados, não seremos capazes de ver a página de login onde será instantaneamente redirecionado para casa. Então a lógica é meio que a mesma. Mas é invertido agora como podemos realmente é descartável multidão realmente da mesma maneira que usamos nosso privado eu vou. Então, aqui, em vez de apenas rota será pobre público Rauer que importamos da pasta Componentes. Agora não precisamos desta importação do roteador reagir. Vamos salvá-lo. E, na verdade, nada será alterado porque não temos dados para o perfil. Então é basicamente isso. É assim que somos capazes de gerenciar nossas multidões privadas e públicas no roteador reagir. Agora vamos confirmar nossas mudanças e terminar este vídeo, então vamos colocar tudo em cima, então vamos comprometer nossas mensagens criadas rotas públicas e privadas para a direita. No próximo vídeo, começaremos a construir a página de entrada. Vejo você lá. 102. Página de login - interação com o Firebase: Ei, bem-vindo neste vídeo, vamos começar a construir página de design. Vamos lá. Antes de começarmos. Só quero mencionar que vamos usar o traje de reação. Você. Por que a biblioteca que instalamos? Vamos utilizá-lo muito. Por isso, abra esta documentação no seu próximo passo, para que tenha sempre acesso a ela. Então vá para a página inicial e clique em componentes. E aqui nesta página você pode encontrar todos os componentes que esta biblioteca nos fornece para oeste. É muito simples de usar, e todos eles são principalmente intuitivos. Então, vamos dizer que se vamos para o componente botão a partir daqui em cada página da empresa, você pode encontrar um monte de exemplos diferentes e casos de uso. E também, se você clicar em mostrou a fonte, você confia como este componente pode ser usado em seu casaco. Você sempre pode copiá-lo e colá-lo. E também, se você só precisa saber qual componente recebe como adereços, você pode rolar para baixo até o fundo e você confia todos os adereços possíveis que podem ser passados para baixo para este componente específico. Tudo bem, então dentro do nosso código, quando eu vou escrever este material, eu não vou fazer referência pode ser algumas vezes, mas na maioria das vezes, porque é melhor intuitivo. Eu não vou explicar isso. Então, se você ainda não sabe o que vai acontecer, navegue até esta documentação. Tudo bem, então vamos começar. Então, vamos navegar para o nosso código e vamos abrir a página de login. E aqui nós vamos começar primeiro, vamos remover este def, e vamos colocar componente recipiente do nosso terno. Você pode pensar que é muito semelhante a contend de bootstrap porque é recipiente já nesta biblioteca. Não é. Só nos dá a exibição do Flex. Então vamos usar grão. E nesta biblioteca, grande é praticamente o mesmo que no Bootstrap. Mas ao contrário do Bootstrap, ele tem sistema de coluna 24. Ao contrário das botas, solte com 12 pentes. Tudo bem, então dentro da grade, nós temos crescer e dentro da linha, nós temos coluna exatamente como essa. Então, nosso cólon vai ser saúde fora de seu máximo com em dispositivos médios. Então, em dispositivos muito pequenos, vamos para pobres e velhas 24 colunas no meio e acima. Vamos colocar 12 agora, dentro desta coluna vamos colocar componente painel, e basicamente vai nos dar alguns tapinhas fora. Ok, então dentro vamos colocar def. E dentro deste difícil definir idade para marcar que vai dizer, Bem-vindo ao bate-papo Underneath vamos colocar Pitak que vai dizer, plataforma de bate-papo progressivo quatro lutas de refeição, algo assim. Tudo bem, vamos verificar. Se eu atualizar a página, posso ver esse estranho, estranho fundo. Isso é porque eu importava coluna do nosso terno Leap Carrossel. Eu não queria isso. Isso é um pouco complicado quando você usa inteligência externa Essence certifique-se importado apenas do nosso terno. Se eu guardá-lo agora, posso ver que realmente funcionou. No entanto, nosso texto não está centrado. Queremos torná-lo centro para que possamos usar uma de nossas classes de utilidade que nós pobres dentro utilitário, como aqui diz, e eles são quase como bootstrap, que possamos definir o nome da classe, centro de texto e ele vai trabalho. No entanto, podemos ver que, se inspecionamos, nosso componente não está completamente centrado em dispositivos grandes. No entanto, no celular, está tudo bem. Isso é porque quando aplicamos este sistema de coluna 12, nosso elemento não é, Digamos tendo-lo. Temos de nos candidatar. Deslocamento. É novamente muito semelhante, como no Bootstrap. Então, para 12 colunas, precisamos aplicar Offset off seis colunas antes dele. Então vamos colocar o deslocamento vazio de seis colunas. E agora nosso grande elemento estará centrado, como podem ver por este estofamento aqui. Tudo bem. Parece bom agora sob uma Disney, se vamos colocar outra definição. E aqui vamos definir nossos botões, assinar com o Google e entrar com o Facebook. Então primeiro vou colocar o botão. Então, como adereços, eu passarei. Vai ser um botão de bloqueio. Ele vai tirar tudo com fora de seu pai. Então eu vou colocar cor, e eu vou colocá-lo em azul. E é isso por enquanto. Então, dentro deste fundo, eu vou derramar componente Aiken do nosso terno, e como eu puder, eu vou especificar que eu posso apoiar quatro Facebook assim. E então eu vou colocar um texto simples, continuar com o Facebook, mas em maiúsculas e o mesmo que eu vou fazer para assinar com o Google. Vou especificar uma cor verde. E em vez de phrasebook, eu posso eu vou especificar Google Aiken e, em seguida, continuar com o Google apenas assim. Agora, o que é dar uma olhada? Está bem, parece bem, mas queremos adicionar alguma margem. Então, para a Disney, vamos colocar o nome da turma e a margem dos três melhores, algo assim. OK, parece bom. Agora precisamos torná-lo centrado verticalmente. Ou talvez em alguma margem para os elementos superiores. Então parece mais agradável. Então, para este grande componente, vamos definir o nome da classe, e vamos colocar margem na página superior. Então esta é a classe que eu defini em um fora dos arquivos utilitários, então ele apenas dá um monte fora de margem para os elementos. Então, se nós inspecioná-lo como você pode ver, margem superior nos dá 150 picos mais. Tudo bem, então parece bom. Agora, e quanto à funcionalidade? Como podemos realmente gerenciar nossa assinatura e finalmente começar a adicionar este Facebook e Google Science. Então, o que precisamos fazer dentro do Firebase gs onde inicializamos nosso aplicativo? Precisamos importar da biblioteca da base de fogo. Então aqui vamos importar a base de fogo assim. Então aqui sob o aplicativo, vamos exportar const disponível, que vai nomear apenas fora e vamos chamar app ponto off e ele vai nos dar o objeto que podemos usar para interagir com base de fogo. Então vamos guardá-lo dentro da assinatura. Nós vamos definir nossos manipuladores para eventos on click para botões. Então vamos colocar em primeiro lugar, digamos que o login no Facebook, e então eu vou fazer o mesmo para o Google no Google assinatura e sua funcionalidade é quase a mesma. Então eu vou criar 1/3 função que eu vou chamar dentro na assinatura do Facebook e dentro na assinatura do Google. Então, vamos nomeá-lo algo como entrar com provedor e provedor como Facebook ou Google. Tudo bem, então como um argumento ele vai receber este provedor e então nós vamos fazer alguma idéia pensar. Então, dentro do Facebook, faça o login. Nós estamos indo para chamar, entrar com provedor e Rubble passar um provedor vai falar um provedor de luta em um momento e aqui também assinar com provedor agora como podemos realmente assinar assim dentro assinatura com provedor, nós pode apenas digitar fora e importado do nosso arquivo misc firebase este fora do objeto que temos daqui se apenas colocar ponto da inteligência. Podemos ver muitas coisas acontecendo aqui. Podemos acessar o usuário atual. Podemos confirmar redefinir senha e diferente. Se escrevermos a assinatura, podemos ter coisas diferentes aqui. Nós entregamos com e-mail e senha com número de telefone com papa com redirecionamento. Então, muitas coisas acontecendo aqui nós estamos interessados em assinar com pop-up e se nós chamarmos isso montado dentro, nós precisamos passar o provedor e ele vai ser fornecido que nós vamos receber como um argumento. Então vamos colocá-lo aqui. Então, o que é esse provedor? Então este objeto provedor que precisamos importar de, digamos, biblioteca firebase e é estático. Então o que precisamos fazer aqui, precisamos importar base de fogo do firebase barra AP novamente, é importante importar do firebase barra ap Então aqui, como provedor, vamos passar o novo firebase dot auth dot facebook off provedor e precisamos chamá-lo vai nos retornar e você provedor objeto que vamos passar como indocumentado para disfunção eo mesmo rebelde fazer para assinatura Google. Vamos colocar uma nova base de fogo fora, mas desta vez o Google fora do provedor assim. Agora, o que realmente associa isso? Manipuladores com botões. Então, para o evento clique para o padrão do Facebook vamos colocar na assinatura do Facebook e para Google, vamos colocar no clique no Google, Entrar assim. Tudo bem, parece bom. Agora esta assinatura com pop up se nós, no entanto, é uma promessa. Por isso, temos de esperar por isso. Vamos converter nossa assinatura com provedor para em uma função de pia e aguardar esta assinatura com Pope up. E então vamos colocar os resultados em resultado viável. E vamos Cônsul olhar e ver. O que recebemos, no entanto, se eu atualizar a página que eu abri conselho, então eu posso ver que respondeu com 400 Arkwright. Isso é bom. Vamos clicar em Continuar com o Google, por exemplo. Tudo bem, você pode ver que ele realmente está fazendo algo, e agora eu posso selecionar uma de minhas contas do Google. Certo, vamos selecionar a mente das minhas contas. E agora você pode ver que eu tenho resultado aqui. Então, é um objeto que tem três objetos diferentes informações adicionais do usuário para que possamos ver que este é o nosso novo usuário. Podemos receber um e-mail com nome, ideias diferentes. Podemos obter uma imagem se o nosso e-mail for verificado. Então, esses dados vêm do Google e você pode ver provedor. Deponho isso ao Google. Em seguida, temos credencial, diferentes tokens de acesso e, em seguida, temos objeto de usuário. Portanto, este objeto de usuário representa o usuário conectado no momento. É geral. E a partir daqui podemos entender se o nosso usuário logou. Nós não estamos. Vamos falar sobre este objeto de usuário em detalhes nos próximos vídeos. Então agora o que podemos fazer Podemos realmente voltar para Firebase Weaken, Ir para autenticação. Aqui podemos recarregar nossa autenticação. Digamos que assine no banco de dados. E aqui nós confinamos nosso e-mail com provedor quando ele foi criado e criado Usuário I d. Então, primeiro lugar, este não é um banco de dados. Isto é como um pequeno banco de dados dentro desta biblioteca de autenticação. Ainda precisamos armazenar nossos usuários dentro do banco de dados. Isto é só para rastrear. Quantos usuários entramos em nosso aplicativo ou algo assim? Tudo bem, então agora vamos realmente modificar nosso código ligeiramente e vamos armazenar nosso usuário dentro do banco de dados. Então, primeiro de tudo, deixe-me colocar, tentar, pegar, olhar aqui porque trabalhamos com promessas e queremos ter certeza de que sempre lidamos com qualquer outro. E, a propósito, apenas para notificar o usuário que estamos atualmente conectados ou se tivermos algum erro, podemos usar o componente de alerta que vem novamente do nosso terno. Então, se tivermos algum erro, vamos chamar alerta, e então se colocarmos ponto podemos ver que podemos ter acesso a informações atter e mensagens de sucesso e aviso . Então vamos colocar a mensagem. Então, como um primeiro argumento, vamos colocar erro essa mensagem, e então precisamos colocar a duração dessa mensagem fora desta mensagem de alerta. Então vamos pobre por segundos em especificado em milissegundos. E se formos assinados, colocaremos alerta. Digamos que sucesso. E então nós vamos colocar assinado com novamente tempo fora quatro segundos. Tudo bem. Parece bom. Agora o que podemos fazer com esse resultado. Como se lembra, recebemos um objeto. Recebemos informações adicionais do usuário e também recebeu objeto do usuário. Agora, verificando se informações adicionais do usuário é seu usuário, então, se o nosso usuário é que está sendo assinado no momento, é um novo usuário irá armazená-lo dentro do banco de dados. Então, como podemos fazer isso? Vamos voltar para Firebase Thaci. Vamos importar outra biblioteca, que será o banco de dados de barras firebase para interagir com o banco de dados e semelhante ao off. Nós estamos indo para exportar banco de dados const ap dot banco de dados assim. Então, sob este banco de dados, valioso podemos interagir com o banco de dados. Vamos saborear a partir da assinatura interna, vamos referenciar o banco de dados, que importamos de diversos firebase. Então vamos colocar a Dot aqui. Precisamos especificar referência, que é basicamente caminho em nosso banco de dados no ritual armazenar nossos dados. Então vamos armazenar nossas informações de usuário sob perfis de barra barra usuário i d. Então vamos abrir interpolação de cordas. E como usuário I d. Nós vamos referenciar usuário ponto Nós podemos ter exibição de e-mail, nome atrasado e um monte de outras coisas relacionadas a este usuário. Mas estamos interessados no usuário I d. Então este usuário I d vai ser o mesmo que este usuário. Eu d dentro da biblioteca de autenticação. Então vai ser como se criássemos um novo usuário. Ele foi adicionado à autenticação o usuário I d é gerado automaticamente, e então vamos usar este usuário I d para armazenar o usuário dentro do banco de dados. Certo, então agora quando tivermos a referência, podemos colocar outro ponto e daqui, precisamos chamar o método SAT. E como você pode ver na descrição, ele grava dados neste local de banco de dados. Então, se eu chamá-lo aqui, vamos armazenar um objeto porque temos formas de dados adjacentes baseados. Então nosso objeto vai ficar assim. Teremos nome e nome vai ser nome de exibição do ponto do usuário. Então também teremos criado em que dirá, quando a conta tiver sido criada. Então, para colocar vamos um carimbo de data/hora apropriado para o nosso banco de dados novamente precisa usar algum estático. Vamos ver a propriedade que vem do Firebase Library. Então nós temos um relatório firebase dot banco de dados ponto valor do servidor ponto ponto carimbo de hora, e ele vai colocar carimbo de hora sanitizado para o nosso banco de dados. Tudo bem, então este ponto disse também retorna essa promessa. Então, sempre que fazemos alguma coisa com base de dados ou qualquer outra coisa, interagimos com qualquer coisa. Muito provavelmente, vamos interagir com promessas. Então é por isso que precisamos esperar e tudo será capturado por este bloco catch e usuário será notificado. Tudo bem, vamos guardar tudo isso porque parece, realmente muito. Agora vamos clicar em, Continuar com o Google. Vamos selecionar meu e-mail e agora estou conectado. Mas é realmente um muito estranho. Isso é provavelmente porque eu tenho esta conta já adicionado Aqui, talvez você me deixe lidar com esta conta. E agora vamos tentar mais uma vez porque precisamos receber um assunto. Tudo bem, então clicamos em, continuamos com o Google, depois selecionamos nossa conta novamente. E agora temos permissão negada esta noite. E não temos isso para colocar ponto na mensagem dela. Mas a coisa é que temos permissão negada e isso é porque se abrirmos nosso banco de dados , tudo bem, vamos clicar, criar banco de dados. Então vamos para as regras. E aqui criamos o banco de dados bloqueado por padrão. Então, o que quer que tentemos fazer com o banco de dados, teremos essa permissão esta noite porque, como vocês podem ver, nós temos permissão de leitura e direitos definida como cai para todos fora de nosso banco de dados. Então, para evitar que o que podemos fazer aqui antes de termos dito essas regras, vamos dizer isso para perfis, e precisamos desafiar, digamos, EBA esque para nossas regras de segurança. E não é essa maneira padrão de definir algo com segurança, mas leva tempo para se acostumar. Confie em mim, é muito fácil de trabalhar. Então temos nosso caminho de perfis. Só precisamos seguir o passado. Então nós armazenamos nossos dados sob perfis de barra usuário i d. Então vamos colocá-lo como um objeto. Então temos perfis, então precisamos colocar uma chave. E porque vai ser algo dinâmico que vai mudar, vamos colocar um cifrão, e então podemos colocar algo como usuário, i d. Isso é apenas para referenciá-lo dentro do objeto aninhado. Deixe-me explicar o que quero dizer. Então, sob este passado, vamos abrir outra vez outro objeto, e dentro, vamos colocar outra chave que vai ser “dot treat” e dot “right”? Exatamente o mesmo que temos aqui. Então para o ponto Leia o que vamos fazer. Vamos fazer referência a esse usuário que recebemos daqui. Agora ele vai como disponível. Podemos fazer referência dentro deste escopo. Digamos que eu apenas destaquei. Então, se o usuário I d que é que um é igual off e off aqui neste vamos dizer contexto fora regras é um valor global que podemos acessar para que possamos ler dados de perfis barra usuário i d. Apenas um usuário i d. i d. Apenas um usuário i d. poderíamos tentar acessar é igual a nós dot usuário i d. Então isso significa, na verdade, apenas o proprietário fora deste documento. Somente o usuário real pode ler seus próprios dados. Qualquer outra pessoa, qualquer outro usuário terá acesso negado. Certo, é assim que definimos as regras para não tratar. Então vamos copiá-lo e vamos aplicar o mesmo para o ponto certo? Então, o que vai acontecer aqui? Como ele vai entender os dois anos assinados bem, vamos voltar ao código quando chamarmos este sinal com pop pop. Agora, nosso usuário está conectado internamente aos serviços do firebase. Então, quando tentamos acessar o banco de dados depois, firebase irá buscá-lo e este usuário I d será conhecido para o banco de dados e vai ser este usuário de ponto auth i d. E então vamos verificá-lo contra o caminho que escrevemos. Agora vamos clicar em Publicar. Certo, regras publicadas. Agora vamos voltar para o banco de dados e, na verdade, vamos copiar, Visite ALS e vamos colá-los, também. Regras do banco de dados para Jason. Então eles estão sempre lá. Certo? Em seguida, volte para a autenticação. Vamos excluir esse usuário e começar de novo. Então eu vou clicar em, Continuar com o Google. Vou selecionar minha conta, e agora não tenho nenhum erro. Agora, eu assinei. Então, agora, se eu navegar de volta para o banco de dados, eu posso ver que eu tenho dados. Eu tenho perfis e que eu tenho usuário eu d exatamente o mesmo que temos aqui. Então é assim que funciona com base de fogo. Tudo bem, então se expandirmos, podemos ver que temos o nosso nome, que é 16 gelado, que é o meu nome na conta do Google. E então nós criamos em que é milissegundos armazenados internamente pela base de fogo. Certo, agora criamos o usuário e gerenciamos nossa página de assinatura. Parabéns. Acho que não foi muito complicado para você. porque há muitas coisas para cobrir aqui. Assinar entrada que este banco de dados de regras de segurança. E tudo vai de uma só vez. Sei que é difícil, mas confie em mim, deixe passar depois de uma hora ou talvez um dia, quando você vai dar uma olhada em tudo isso mais uma vez. Não será assim tão complicado. Tudo bem, então vamos cometer nossas mudanças e terminar este vídeo, então nós vamos puxar, pegar em tudo, e então nós vamos cometer algo como editar login na página e assinar e com Facebook Slash Go menina. Tudo bem. Perfeito. No próximo vídeo, continuaremos nossa conversa com autenticação e iniciaremos nosso gerenciamento de usuários. Vejo-te isso. 103. Criando o perfil - API de API de contexto e gestão global: Ei, neste vídeo, eu gostaria de falar sobre contexto, um p i e gestão global do estado. Quando se trata de gerenciar perfil de usuário como podemos abordar isso, sabemos que ele deve ser acessível globalmente a maior parte do tempo dentro de cada componente. Imagine um componente muito menos na APP. Este componente precisa exibir o nome de usuário que está atualmente conectado em questão é onde gerenciamos esse usuário exatamente. Vamos supor no componente APP. Então, para obter nome de usuário, devemos passá-lo através dos adereços para cada próximo componente todo o caminho abaixo da árvore. Mas isso não é legal. Nós temos, como, 10 componentes acima, e cada componente está desempenhando um papel na medida em que isso é chamado de perfuração de prop. Quando algum valor está sendo passado para baixo, os adereços em um monte fora níveis profunda, isso não é bom e deve ser evitado para evitar problemas ajoelhados. Há contexto, um P I em reagir. Ele introduz o conceito off provedor e provedor de consumidor é um componente que fornece todos os seus filhos com algum valor ou contexto. Consumidor é um componente que consome o contexto e obtém o valor usando contexto. AP I. Podemos gerenciar facilmente o nosso usuário no componente provedor e, em seguida, consumidores. Em qualquer componente. Queremos evitar a perfuração de sondas e componentes intermediários. Nós iria criar contexto de usuário e colocar nome de usuário como seu valor. Em seguida, nós iria embrulhar componente em torno do provedor de usuário. Então, basicamente, todos os componentes têm acesso ao contexto do usuário para consumi-lo dentro do componente onde precisamos obter o valor de contexto que chamaríamos usar o gancho de contexto. Dessa forma, somos capazes de obter o nome de usuário de qualquer lugar dentro do nosso aplicativo. Não há limitações de uso de contexto. Nós somos capazes de colocá-lo em qualquer lugar no componente APP em torno da página inicial em torno de multi página formulário e assim por diante. Tudo bem, vamos realmente ver como o contexto AP I funciona no exemplo do nosso aplicativo de bate-papo. Vamos lá. Então, na pasta de recursos, vamos criar outra pasta que vamos chamar contexto. E aqui vamos colocar todo o nosso contexto criado. Vamos criar novo arquivo e nome móvel que talvez não contexto de usuário, mas contexto de perfil. Eu acho que é mais adequado no nosso caso, Então vamos colocar perfil ponto contexto cãozinho s. Então, qual é a nossa estratégia? Nós vamos criar este contexto e vamos colocá-lo dentro do nosso componente APP, para que qualquer outro componente dentro da nossa aplicação possa ter acesso a ele. Então, o que precisamos para criar um contexto? Nós simplesmente precisamos chamar criar contexto que vem do pacote de reagir. Então vamos colocá-lo disponível. E digamos que vai ser um contexto de perfil assim. Agora precisamos criar um provedor, um componente, um componente, e que irá fornecer a todos os seus filhos com este contexto de perfil. Então vamos pobre exportação CONST. Provedor de perfil. E vai ser um componente. Então isso vai ser uma função assim. Tudo bem, agora o que precisamos para embarcar aqui? O que vai voltar? Ele vai retornar o provedor de pontos de contexto de perfil e, em seguida, dentro deste provedor, precisamos de suporte de todos os nossos componentes, o que quer que passemos por dentro. Por isso, vão ser os nossos Filhos. Este provedor de perfil é apenas um rapper, então vamos destruí-lo como um adereço aqui e colocá-lo dentro de um componente provedor assim . Tudo bem, agora, se temos ou podemos ver que reagir deve estar no alcance. Tudo bem, deixe-me importar reagir. E algumas pessoas se livram desse aviso agora como somos capazes de fazer qualquer coisa. Então, como este é um componente, podemos fazer nossa gestão estadual diretamente aqui. Vamos navegar Teoh nossa rota privada, e aqui sabemos que colocamos isso por enquanto. Colocamos este touro em valor. Isso cai por padrão. Então vamos tratar disso e ele consumirá o nosso contexto. Então vamos colocar isso. Digamos, ouro. Dentro deste contexto, vamos criar, vamos ver perfil e dito Perfil como estado usado, que vai ser, digamos, digamos, Abul em valor por enquanto, apenas para demonstrar como contexto funciona a fim de passar em valor para esses contextos, precisamos colocá-lo como um adereço para fornecer seu componente aqui. E precisamos passar nosso perfil assim e vamos conhecer o set profile. Não vamos destruí-lo assim. Tudo bem, estamos prontos para ir. É isto. É assim que podemos gerenciar nosso contexto agora para realmente usá-lo dentro de nosso aplicativo dentro de nosso componente. Precisamos colocá-lo aqui no componente aplicativo apenas em torno do interruptor. Então vamos digitar o que chamamos de provedor de arquivos raw. E é isso. E eles vão pensar sobre o contexto que ele pode ser muito personalizável porque este é apenas um componente. Vamos dizer que se precisamos obter usuário com específico I d. Podemos simplesmente passar este usuário i D como um adereço, e então podemos pegá-lo de adereços aqui e, em seguida, colocar o nosso A P I chamar ou qualquer outro gerenciamento de estado relacionado a este usuário particular i Isso é realmente, muito legal, Tudo bem, Tudo bem, agora que nós fornecemos todos os nossos componentes com provedor de perfil sem pode consumi-lo. Então, como podemos fazer isso? Como você se lembra eu mencionei usar o gancho de contexto. Então, dentro de nossa rota privada, Em vez de fazer isso, podemos simplesmente fazer perfil constante igual a usar contexto que vem de reagir pacote e, em seguida dentro dos registros dentro pai é é que precisamos especificar contexto que criamos. Vai ser este contexto de perfil, e é realmente tedioso referenciar contexto de perfil cada vez que chamamos com contexto de uso . Então, para evitar isso, podemos criar outro gancho, um rapper para contexto de perfil para torná-lo mais acessível. Então, a partir de contatos de perfil Sim, arquivo, poderíamos exportar Const. Digamos Use perfil Hook, que vai ser usado contexto, contexto de perfil assim. E agora diz que não pode ser chamado. Oh, desculpe-me. Vai ser uma função que retorna o que quer que este contexto de uso retorne. E esse contexto de uso nos retorna um valor. Então, a partir do nosso código, podemos simplesmente chamar o perfil de uso e vamos remover o contexto de uso a partir daqui. E agora, esse perfil será esse valor que passamos aqui. Então agora podemos verificar se nenhum perfil, então vamos redirecionar e vamos fazer exatamente a mesma coisa para o perfil público. Então daqui, em vez de falso, vamos usar o perfil, e é basicamente isso. Agora eu já lancei o aplicativo, Então, se eu tivesse um fresco, nada mudou. Como você pode ver, se eu tentar acessar a página inicial, estou sendo redirecionado para entrar para que nada tenha sido alterado. No entanto, agora gerenciamos nosso perfil como um estado global que podemos acessar de qualquer componente, não apenas da multidão pública. Assim, cada componente que está dentro do provedor de perfil pode acessar seu contexto. Tudo bem, com o contexto de uso, Gancho e nós criamos um wrapper em torno do contexto de uso com contexto de perfil, que é usado perfil. Então agora é ainda mais fácil de usar para nós acessar. Além disso, é muito importante mencionar que digamos que criamos esse contexto de perfil. Ou talvez imaginemos que desfilamos algo como contra-contexto. Digamos que 12345 está bem, e dentro do nosso aplicativo. Em vez de usá-lo assim, usamos várias vezes. Então, digamos que para entrar na página que temos, digamos provedor contador de contexto contador como este tudo certo, eo mesmo vale para casa. Então nós temos isso assim. Agora temos dois contatos diferentes. Sua definição é a mesma, mas eles são diferentes. Então, se dentro de sinal na página, vamos dizer tentar acessar contexto fora do contador, em seguida, vamos chegar a um. Bem, você, se tentarmos acessar o mesmo contexto com o contexto de uso, gancho dentro da página inicial, mas terá outro valor porque eles também, têm estados diferentes. Tudo bem, então é como conseguir separar estados, mas com uma definição faz apenas para apontar que é diferente. Então é basicamente isso no próximo vídeo, o que vamos fazer, vamos continuar trabalhando com nosso provedor de perfil e as pessoas finalmente gerenciaram nosso usuário do firebase conectado . Vejo você lá. 104. Gestão de estados globais com contexto: Ei, bem-vindo neste vídeo. Vamos gerenciar nosso usuário do firebase conectado com contexto. AP I Vamos No vídeo anterior quando chegamos a conhecer contexto AP I criamos provedor de perfil . Então agora vamos usar o estado real em vez de apenas um touro em valor. Então vamos substituir false por null. E vamos também chamar, Vamos definir a função de atualização do perfil definido. Tudo bem, então vamos usar o ato Yousef para obter o usuário da base de fogo quando o componente for montado. Então vamos usar o seu fato e ouvir o que vamos fazer. Vamos cancelar o estado mudado. Então, da base de fogo, vamos usar nosso objeto. E se colocarmos ponto se escrevermos, vemos que podemos usar em ambos os estados alterados. Então, isso no estado dos EUA mudou. Permite-nos subscrever o usuário atualmente conectado dentro da base de fogo. E dentro desta assinatura, somos capazes de acessar fora do objeto. Então vamos colocar assim e para análise. Cônsul , desligue o objeto. Agora, se navegarmos de volta para o aplicativo se abrirmos nosso conselho, veremos isso fora do objeto. E se expandimos é exatamente o mesmo objeto quando entramos com o Facebook ou Google. Então é assim que ele pode ser gerenciado facilmente. Se fôssemos assinados para o aplicativo, não veríamos esse objeto. Seria agora. Então, a questão é por que estamos vendo isso atualmente? Como os gerentes do firebase têm sessões para nós, não precisamos implementar tudo. Uma vez que estamos conectados, autor, objeto será preenchido automaticamente para nós e gerenciado para nós. Nós não precisamos fazer tudo o que precisamos para apenas entrar ou sair e, em seguida, o objeto do usuário estará aqui. Certo, usando essa informação, o que podemos fazer em vez de apenas Cônsul, , vamos perguntar se ambos os objetos existem. Se for preenchido com algum valor, então vamos fazer alguma coisa. Caso contrário, se este objeto do Earth não for o objeto, se ele ainda estiver, então o usuário não está conectado. Então este estado ligado mudou, chamado pelo menos uma vez quando o componente monta e se não estamos conectados, então ele vai ser definido para saber também se nós sair do aplicativo porque esta é a assinatura. Será atendido por esta chamada. Para trás e para fora do objeto será tal saber. Então, dentro disso, vamos definir perfil para agora e aqui quando temos o objeto que podemos chamar, definir perfil e colocar alguns dados de perfil que vamos definir aqui. Então, nossos dados de perfil vai ser o próximo que vai ser o primeiro usuário I d. que vamos obter de ambos objeto ponto seu i d Que podemos ver aqui. E isso refletirá nosso usuário que eu d em muitas bibliotecas que vimos na base de fogo. E também eu era usuário I d dentro de banco de dados em tempo real. Então também queremos talvez e-mail. Então vamos passar o e-mail de ponto de objeto, e também, precisamos de nossos dados do banco de dados em tempo real, então precisamos realmente obtê-los aqui. Então o que vamos fazer como podemos ver, perfil já está declarado. Tudo bem, talvez menos. Basta nomeá-lo dados e disse dados de perfil. Ok, então aqui para obter dados reais do banco de dados para este usuário, precisamos chamar novamente o banco de dados do MISC Firebase. Então vamos colocar referência de novo, vamos fazer perfis. Então nós vamos derramar fora do objeto ponto seu i d Então nós mudamos aspas para a população contador de cordas e então nós queremos derramar assinatura de tempo aéreo para o nosso líder de usuário. Então, se algo mudou, então queremos ser notificados sobre isso. Não queremos gerenciar tudo manualmente. Assim, com base de dados em tempo real e com realmente qualquer banco de dados e base de fogo, é muito fácil. Então, para obter dados apenas uma vez que chamamos ponto uma vez método para colocar uma assinatura em tempo real sobre esses dados que precisamos colocar, então precisamos chamá-lo como uma função e primeiro argumento. Precisamos especificar o alvo, o evento. Digamos que sim no valor. Queremos executar este Colback. Então, sempre que nossos dados nesse caminho dentro do banco de dados mudam como qualquer coisa, esses Colback serão disparados como todas as vezes e receberemos um instantâneo. Então vamos tirar uma foto do Cônsul Sorte assim. Então agora estamos dentro de casa porque nós realmente temos alguns dados de perfil. E como você se lembra, dentro da rota privada, verificamos o perfil para que não vejamos a página de login. Ok, isso é bom. Então, nosso instantâneo de dados tem referência de nó chave e algumas outras coisas e metadados relacionados a esse snapshot nesses caminhos dentro da base de dados. Bem, dentro do instantâneo temos este método. Ele é chamado instantâneo ponto camisa snap valor, valor escuro. E ele vai nos dar os dados do banco de dados, Informar fora do objeto JavaScript. Então, vamos dizer que dados de perfil são iguais a instantâneo, não valor. E agora vamos ver os dados do perfil do Salak como este. Vamos verificar isso. Agora. Se eu atualizar a página, eu posso ver ter um objeto com anúncio criado e nome, que é ela parece 16. Exatamente os mesmos dados que temos dentro do banco de dados. Agora, o que precisamos fazer? Podemos destruir este perfil. Dados enfraquecer estrutura D, nome e criou que assim. E aqui podemos mover esse objeto de dados para essa assinatura assim, e então o que podemos fazer. Também podemos mover isto nos dados do perfil para aqui. E para esses dados podemos colocar nome e criar exatamente assim. Então, o nosso perfil no final teremos nomeado criado em seu e-mail i D. Certo? Então é isso. E agora passamos esse estado de perfil de dados para baixo no contexto. Então, dentro do nosso privado, também precisamos de alguma forma manter o controle se estamos sendo registrados no momento. Então precisamos colocar o estado de carregamento para colocar um girador ou outra coisa. Então vamos colocar outro estado que vamos nomear está carregando e definir está carregando por padrão. Vai ser definido como verdadeiro. E logo depois que dissemos que o perfil que vamos chamar de set está carregando e colocando-o em falso. Ou se não tivermos nenhum perfil, vamos ligar para o Set está carregando e colocar quedas também. Tudo bem, agora isso está carregando. Vamos passar com o nosso contexto. Então, em vez de apenas passar perfil dentro, vamos passar um objeto com está carregando estado e também perfil. Então, agora, dentro de nossa rota privada, quando usamos o perfil, recebemos um objeto com seu perfil e objetos de perfil dentro. Então nós vamos estruturar nosso perfil a partir dele e o mesmo celular fazer quatro usar perfil. Então agora o que podemos fazer aqui, dentro privado para fora nós podemos realmente usar isso está diminuindo. Então vamos D estrutura está carregando e o que vamos perguntar. Então vamos colocar outro se aqui, e vamos perguntar se nossos dados estão carregando e ainda não temos dados de perfil. Então vamos devolver o contêiner do nosso terno e lá dentro, vamos colocar a Lei Ordem. Vai ser um spinner, também um componente do nosso terno, e vai ser centrado. Ele vai ser centrado Vertical e tamanho lobo whoops. tamanho desligado é igual a M d. Então o conteúdo vai ser carregado, e a velocidade vai ser lenta. E vamos movê-lo para evitar que ele lhe emprestou. Vamos movê-lo para o topo assim. Muito bem, esta é a nossa primeira condição, e depois também precisamos modificar essa. Vamos perguntar se não temos perfil, e se não temos apenas estado de carregamento, então vamos redirecionar. Tudo bem, então vamos checar. Agora. Quando atualizamos a página, podemos ver o girador muito legal, certo? E somente quando obtemos os dados, nós realmente vemos a página inicial. Muito bem, vamos fazer exactamente a mesma coisa pela multidão pública. Então vamos copiar essa lógica e colocá-la aqui. Vamos Destructor está carregando e vamos perguntar se temos está carregando e não temos perfil então vamos colocar de novo estado de carregamento como este se tivermos perfil e, bem, pode ser um pouco complicado. Então, se temos o perfil e o carregamento está definido como falso, então vamos redirecionar. Tudo bem, é basicamente isso. Eu só quero Teoh fazer mais um passo importante aqui porque estamos trabalhando com assinaturas em reagir. Sempre que trabalhamos com ouvintes em tempo real para os dados, usamos uma assinatura. Portanto, sempre que tivermos uma assinatura, precisamos cancelar a assinatura dela quando não precisarmos dela. Então isso no palco dos EUA mudou. Se você pode ver ele retorna base de fogo cancelado. Então ele nos retorna uma função que precisamos chamar para cancelar a assinatura desta assinatura no estado fora alterado. Então vamos colocá-lo, vamos dizer off no submarino e vamos cancelar isso no sub e nossa função de limpeza fora do ato Yousef . Então vamos retornar uma função e aqui vamos cancelar. Então, apenas assim e o mesmo se aplica para nossa referência de banco de dados aqui. Então, neste passado, colocamos um ouvinte em tempo real que está no valor, e é o nosso Colback. Então nós queremos ter certeza de que nós cancelamos a assinatura dessa também. Então aqui, digamos, dentro deste uso de fato, vamos derramar, deixa uma referência de usuário. Em seguida, vamos atribuir Use uma referência para referência de banco de dados neste caminho como este e seguida, usuário áspero no valor. Vamos executar este retorno de chamada sempre que não temos nenhum dado. Se o nosso usuário não estiver conectado, Se não tivermos nenhum outro objeto, vamos perguntar se o usuário ref está definido. Então nós vamos ligar, usar ponto áspero fora porque se eu colocar ponto aqui, eu posso colocar eu poderia colocar uma vez e também eu posso adiar e isso fora como você pode ver desprende um retorno anteriormente ligado com em para que possamos. Desta forma, podemos cancelar a inscrição destes chamada de volta a partir destes caminho dentro do banco de dados. Na verdade, o mesmo que faremos dentro de nossa limpeza para efeito de uso. Então este sempre que assinamos e este sempre que nós quantificamos o componente, então aqui nós vamos perguntar se o usuário Rafa, então vamos usar um ponto ref fora de cancelar a assinatura desta referência de usuário. Tudo bem, então é basicamente isso. Espero que não tenha sido uma causa muito confusa para mim. Quando? Pela primeira vez. Quando eu vi, era , mas no final, faz sentido. Tudo bem, vamos cometer nossas mudanças e terminar este vídeo. Vamos colocar em tudo. Então vamos cometer tudo com a mensagem. Algo como o usuário da idade do homem com contexto de perfil Put riel time subs algo assim. Muito bem, vemo-nos no próximo vídeo. 105. Começar a criar a barra de lateral e o painel: Ei, bem-vindo. Agora que temos o fluxo de assinatura completo, vamos finalmente começar a construir nossa página inicial. Vamos começar a partir do local esquerdo. Então primeiro vamos construir nossos botões do que a lista de chat e depois vamos para o Maine. Janela Shatt. Vamos para dentro de páginas em vez desta definição. Vamos definir a nossa coragem. Então ele vai ser grande componente, que vai ser fluido e classe Nome vai ser um Chuan 100. Vamos fazer com que seja em altura total. Então dentro vamos para o elemento de controle e, em seguida, vamos derramar elemento de coluna do nosso terno. Então, para dispositivos pequenos, levará todas as colunas, que são 24 colunas e começando a partir de dispositivos do meio. Vamos colocar algo como oito. Não saúde, mas oito. E dentro desta coluna vamos usar o componente da barra lateral, mas não o que vem do nosso terno. Aquele que nós mesmos criaremos. Vamos salvá-lo. E sob componentes, vamos criar um novo arquivo, que vamos nomear Sidebar cãozinho s. Vamos abri-lo e vamos pedir uma pasta para um rap. Dave, eu vou colocar o nome da classe fora da altura total e depois um pouco fora de bater no topo. Então, dentro vamos dividi-lo em dois elementos. Então teremos a parte superior com nossos botões e na parte inferior teremos uma lista de salas de bate-papo . Então vamos primeiro criar def para a nossa parte superior e na parte inferior porque ainda não temos nenhuma conversa na lista. Vamos apenas resumir texto como este. Então, dentro deste diferente vai derramar malabarismo painel que irá criar em um momento e salvá-lo . Então, outros componentes. Vamos criar nova pasta, que vamos nomear o relatório aqui. Bubble definiu dois arquivos. Primeiro vai ser togs indexados, que vai ser o nosso componente de painel, mas vamos gerenciar tudo, mas por enquanto vamos mantê-lo vazio. Então vamos nomeá-lo, relatório pai e apenas colocar Olá insight e segundo elemento vai ser malabarismo painel. Então, aqui vamos definir o nosso botão e o próprio drover. Então primeiro queremos nos livrar do embrulho Div. Então vou definir um botão aqui, que vai ser o nosso Tobler. Digamos que vai ser um elemento de bloco. Vai ter colarinho azul e lá dentro vamos colocar Aiken que importamos do nosso terno. Aiken vai ser essa palavra. E, em seguida, o texto vai ser painel como este. Agora vamos realmente dizer com e vamos ver, o que temos? Então, se atualizarmos a página dentro da barra lateral, não temos painel até ir, Vamos importar. E também dentro de casa, não temos barra lateral. Vamos importar também. Tudo bem, vamos verificar. Certo. Então temos o botão. Mas quando clicamos, nada acontece. Então vamos definir o nosso componente Drover em ou Drover, elemento aqui ao lado de Button. Eu vou colocar Drover que vem do nosso pacote de terno e não é um elemento tão fechante dentro. Nós realmente precisamos derramar elementos drover, mas vamos defini-los dentro deste arquivo NGS adulto índice. Então, para esta luta, nós só precisamos definir esta propriedade show e ele vai ser Deve ser um valor bowline que irá indicar quando este drover é aberto. Então precisamos definir sobre evento altura e, em seguida, também precisamos definir colocação. No nosso caso, ele vai ser à esquerda ou agora precisamos realmente definir nossos manipuladores ou estado para o nosso drover. Precisamos manter o controle de seu estado por conta própria. E uma vez que nós vamos ter um monte fora motéis ou drovers em nossa aplicação, e nós estamos indo para re usar um monte da mesma lógica, eu propus para criar uma esperança personalizada que vamos nomear o estado do modelo de uso e ele irá expor apenas três elementos está aberto na altura e no show. Então, sob MISC, vamos criar novos ganchos personalizados de arquivo GS. Aqui vamos definir uma nova função, que vai ser o nosso gancho, que vamos nomear usar estado modelo. Ele receberá o valor padrão. Digamos que o valor padrão, que será definido como false se for indefinido. Dentro, vamos definir estado, e por padrão este estado será o nosso valor padrão que passamos como um argumento e também aqui vamos definir algumas funções auxiliares. Digamos que sim. Primeira função vai ser aberto e será um envolto uso frio de volta com antecedência para torná-lo otimizado, e ele vai chamar, disse ST, e vamos defini-lo como verdadeiro e o mesmo que aplicaremos para fechar. Mas em vez de verdade, vamos derramar falso aqui e deste gancho, vamos voltar ao nosso estado. Talvez vamos renomeá-lo também está aberto, e o conjunto aqui está aberto. Então, a partir deste gancho, vamos retornar é aberto, aberto e fechar funções auxiliares. E não se esqueça de exportar o estado do modelo deste ano a partir de ganchos personalizados. Tudo bem, então dentro do árabe ou alternar, nós vamos usar este estado modelo de uso que nos retorna está aberto. Em seguida, ele nos retorna perto e aberto. Então agora podemos usá-lo. Então, na altura, vamos especificar com nossa própria função de roupas que definimos no show de ganchos. É um touro em valor, tão pouco especificar está aberto e também para o nosso botão. Quando clicamos nele, queremos mostrar o Drover. Então, para este botão para no evento clique, vamos especificar Apenas abrir. Tudo bem. E agora precisamos colocar algo dentro do Rover. Vai ser este elemento. Então vamos definir painel e você vai ver que ele será importado do ponto Isso significa que ele será importado da nossa pasta atual. Então por que colocamos o Índice Gs assim? Então, se o usarmos em qualquer outro componente, digamos dentro de páginas e a maneira como importamos, vai ser assim. Vamos importar de componentes. Esse relatório não especificará Dashboard Index GS porque ele é nomeado como índice. Sim, podemos especificar apenas o nome da pasta onde este índice pontos gs re sites e ele vai funcionar. Tudo bem, então agora vamos salvar tudo e vamos dar uma olhada. Agora, se eu clicar no painel, funcionou perfeitamente. Então eu acho que é isso para este vídeo. No próximo vídeo, continuaremos e tornaremos nosso mortal um pouco mais responsivo. Porque se eu vou apenas clicar nele, se eu vou, você sabe, você sabe, apenas redimensionar a janela, você pode ver que ela permanece estática. Este não é um comportamento amigável, então vamos corrigi-lo mais tarde. Mas por enquanto, vamos confirmar nossas mudanças, e vamos dizer, começando ou começou a construir o componente da barra lateral. Tudo bem. Perfeito. Vejo-te no próximo. 106. Barra de sites responsivos usando media: Ei, bem-vindo nisso. Nós vamos fazer nosso trabalho, er, er, que criamos no vídeo anterior responsivo. O que quero dizer é que agora, se tentarmos inspecionar nosso elemento e se abrirmos Drover, se redimensionarmos a janela, ela permanece estática. Bem, não é nada sensível ao que podemos fazer para consertar isso para Drover. Há esta sonda disponível, que está cheia, o que significa que Drover estará disponível para tela cheia. Vamos verificar esta propriedade completa e vamos ver, o que temos? Então, agora, quando abrimos quando estamos em dispositivos desktop, podemos ver que é tela cheia. No entanto, se estamos em dispositivos móveis, parece bom. Então, o que? Enfraquecer Dio? Idealmente, gostaríamos de habilitar essa propriedade de tela cheia somente quando estamos em dispositivos móveis . Então precisamos que alguns determinem programaticamente bem, podemos realmente usar consultas de mídia, mas eles estão disponíveis apenas e CSS Mas com ganchos, podemos alcançar o mesmo resultado programaticamente. Então, vamos abrir o arquivo de ativos a pasta de ativos e aqui confinado usar media query gs. Vamos abri-lo e vamos copiar este gancho agora Vamos acelerar este gancho para nossos porcos personalizados dgs e vamos importar usar um fato de reagir. Então, agora, o que este gancho faz ele ganchos na janela muito mídia um p I, e ele nos permite manipular consultas de mídia. Programaticamente eu não vou mergulhar em detalhes aqui. Vamos ver como funciona. Então eu vou salvar o arquivo. Então vamos voltar ao Dashboard Tuggle. E aqui vamos chamar isso de usar gancho de consulta de mídia e dentro precisamos passar um ponto de quebra de mídia . Então vamos dizer que vamos abrir nossas atenuações pais e vamos passar Max com 1992 pixels. E agora este gancho retorna em Bullen que indicará se é verdadeiro ou falso. Então, usando isso, podemos verificar se estamos no dispositivo com 992 pixels. Então vamos pobre é móvel e este Bullen vamos passar adereço cheio de dentes. Então, quando estamos em dispositivos móveis, teremos a propriedade completa habilitada. Quando estamos em dispositivos desktop, isso será definido como falls e nós não teremos essa propriedade completa se nós salvá-lo. Vamos voltar ao aplicativo agora se estivermos em dispositivos móveis. Se o tamanho do nosso ecrã for inferior a 992 pixels, temos o nosso Drover completo e funciona perfeitamente. E se estamos em dispositivos desktop, temos este Drover estático que não é alterado. Bem, este é exatamente o comportamento que queríamos. Então aqui terminamos com nossa capacidade de resposta. Vamos terminar este vídeo e confirmar nossas mudanças. Vamos colocar tudo para o get e vamos nomear o nosso commit como editar usar gancho de consulta de mídia e fez Drover responsivo. Está bem, Perfeito. Vejo-te no próximo. 107. Criando o painel - parte 1: Ei, bem-vindo neste resgatável. Continue construindo nossa barra lateral e vamos começar a construir exatamente Dashboard. Vamos lá. Então, primeiro, vamos abrir togs índice e aqui em vez de visitar se vamos usar elementos Drover. Então, já que não temos nenhum rapper porque o definimos dentro do aeroporto alternar esses Drover, vamos usar o insight fragmento de reagir como este. Então nosso trabalho, elementos er será drover dot não intitulado sobre ponto Heather Inside cabeçalho. Vamos ter título drover dot e porque off V s código casca com fragmento reagir Agora eu tenho essa duplicação de dados, mas isso é bom. Então em seguida você teve er nós teremos Drover Dot Body e então teremos Drover Dot Footer assim. Então dentro do corpo ia exibir os dados do usuário. Então, aqui vamos bombear. Digamos que h três elemento e, em seguida, vamos dizer, Ei, usuário ou temos perfil. Temos nome de ponto perfilado. Então este perfil será o nosso perfil que obtemos do gancho de perfil de uso. Esse é o nosso contexto. Então vamos chamar o perfil de uso e eu não tenho inteligência. Então vamos abrir o contexto do perfil. E agora, se eu colocar inteligência, será importante para mim. Tudo bem. Bom. Então dentro do corpo, temos texto exibido dentro do título. Vamos puxar apenas painel e rodapé dentro, vamos adicionar botão Sign out. Então vamos adicionar elemento botão. Vai ser um elemento de homem. Ele terá cor vermelha e para unclipped vamos especificar em Sign out e vamos derramar Sign out como texto. Tudo bem, então talvez vamos apenas remover um clique por enquanto e vamos apagar este H3 tack na parte inferior. Vamos verificar isso. O que temos como resultado? Nós estamos certos. Perfeito. Então agora temos ódio. Ela parece ter 16 anos, que é o nosso nome de utilizador. E, em seguida, temos logout botão, mas ele não tem nenhuma funcionalidade ainda, então vamos adicioná-lo. Bem, quando sair do aplicativo, queremos que você também feche esta janela do modelo. Mas esta função próxima recita dentro do Data Board Togo. Então eu propus para definir um sair, função dentro do painel togo e, em seguida, passá-lo para baixo para o componente painel. Então aqui vamos colocar Const em sinal de saída. E porque temos esse estado aberto aqui, toda vez que abrimos e fechamos o tempo todo. Teremos uma nova cópia fora desta função no logout. Então, queremos manter esta cópia. Queremos que você memorize. Então vamos usar chamada de uso de volta com antecedência e dentro vamos colocar a próxima lógica. Precisamos ligar para Sair, que está disponível no juramento. Objeto? Oh, não assinar. Apenas saia. E é isso. Isso vai sair completamente. Nosso usuário atual. Tudo é gerenciado pela base de fogo. Então precisamos colocar alerta, que vai ser um alerta para alerta. Vamos dizer, assinado fora. Vai durar quatro segundos e depois fecharemos o Drover também. Então, porque vem do nosso gancho personalizado, precisávamos passá-lo como uma dependência. Mas isso é bom. A função de roupas é memorizada dentro do estado do modelo de uso porque colocamos dentro. Use CLO de volta como você se lembra. Não, vamos passar. Sair no painel e no painel interno. Vamos consumi-lo. Sair. Está em maiúsculas? Sim, é. Então, quatro em diante. Sair. Clique. Vamos colocar a função de saída. Tudo bem? Parece bem. Agora vamos dar uma olhada. Se abrirmos nossa placa, se clicarmos em sair agora, estamos desconectados. E a questão potencial pode ser por que somos redirecionados para entrar na página. Isso é porque dentro do nosso contexto, temos isso fora do estado mudado. Então, quando sair porque é uma assinatura em tempo real, firebase irá buscá-lo. Ele vai sair do usuário, e este Colback será demitido. Então, quando não temos fora do objeto, chamamos set profile para saber. E quando temos definido perfil agora ou indefinido, se olharmos dentro rota privada, redirecionamos o usuário para entrar. Então é exatamente isso que está acontecendo. Então agora temos o sistema completo de assinatura e saída, que funciona perfeitamente. Tudo bem, então para verificar se tudo funciona. - Tudo bem. Vamos entrar mais uma vez e vou selecionar exatamente a mesma conta novamente. Agora estou redirecionado. Eu estou conectado e novamente, eu tenho ódio. Ela parece ter 16 anos. Tão perfeito. Funciona como deve funcionar. Agora vamos confirmar nossas mudanças e terminar este vídeo. Vamos bombear, pegar em tudo, então nos comprometemos. Começou a criar um painel e ele sair botão e exibir o nome do usuário. Muito bem, vejo-te no próximo. 108. Criando o painel - componentes reutilizáveis e editáveis (parte 2): Hey, bem-vindo neste líder foram continuar a construir que carne de porco e verbal criar um componente que vamos reutilizar várias vezes em toda a nossa aplicação em alguns lugares. Então vai ser uma entrada com os dois botões que enquanto eu estava muito editada. Então, quando o salvamos, nós realmente atualizamos dados dentro do banco de dados. Vamos lá. Então, primeiro, o que eu proponho é criar o componente real. Então, em componentes, vamos criar um novo arquivo credível na porta por enquanto. Deixe-o estar vazio. Vamos só pôr um “olá” aqui. Vamos primeiro definir como vamos usá-lo. Vamos abrir esse arquivo de palavras aqui em Ei, nome do perfil. Vamos colocar o divisor do nosso terno. E, em seguida, vamos definir Edita ble importação. Então, o que? Adereços deve re passar insight. Então, primeiro de tudo, vamos passar o valor inicial, que será triste para a entrada. Então vamos colocar o valor inicial, que vai ser o nome escuro do perfil. Tudo bem, então também precisamos definir a função segura e que será disparado quando salvarmos a entrada. Então vamos colocar em segurança e vamos defini-la aqui. Então vamos colocar em seguro e esta função de retorno de chamada, ele receberá o mesmo valor que um argumento. Então vamos colocar novos dados e para o nosso vamos deixar esta função vazia. Além disso, queríamos relatar talvez algum rótulo na frente da entrada, então teremos a opção de passar um componente reativo como um adereço para o componente amplo comestível . Então vamos definir algo como seis anos de idade. Talvez, vamos colocar que vai ser nome Nick e nome da classe vai ser margem inferior para porque queremos adicionar algum espaço entre o nosso rótulo e entre a entrada real. E também podemos passar outros adereços que serão redirecionados elemento de entrada Judy. Então talvez também possamos passar algo como nome, que vai ser, no nosso caso, apelido. Então, o que será inserido com o nosso apelido que seremos capazes de adicioná-lo? Tudo bem, Cool. Então vamos abrir nosso componente e começar a construir. Então primeiro temos valor inicial. Trabalhei em um dos principais adereços. Em seguida, vamos destruidor em seguro venerável também tem rótulo, que vai ser esta idade seis, e há uma chance e que este rótulo não será passado. Então vamos colocar agora VT dobra e, em seguida, também algumas outras coisas, como espaço reservado. Talvez assim. Vamos pobre espaço reservado. E por padrão, será dito, Escolha algo como certo, Seu valor. Tudo bem. E então também, o que eu proponho é derramar um adereço que representará nossa mensagem vazia quando alguém tentar salvar nossa entrada e ela está vazia para que possamos colocar como um valor global que dirá que entrada está vazia. Mas e se quisermos personalizá-lo? Então, vamos também passá-lo como uma mensagem vazia prop. E por padrão, se não for especificado em adereços, diremos que será no tribunal, seu vazio tudo bem, e qualquer outro adereço será nossos adereços de entrada. Tudo bem, então para isso ao vivo o que vamos fazer Então aqui, logo antes do elemento de importação real, vamos portar rótulo. Tudo bem, então vamos derramar a entrada que vem do nosso terno. Então, para esta entrada, no primeiro adereço, vamos passar nossas colheitas de entrada, e vamos sobrescrever algumas delas. Então vamos sobrescrever espaço reservado, que vai ser este lugar titular de adereços. Então também teremos outras coisas que gerenciaremos dentro deste componente, como seu estado interno. Então, quando vamos editá-lo, vamos gerenciar tudo a partir daqui. Então vamos colocá-lo aqui com antecedência. Então vamos definir novo estado, que vai ser, digamos, apenas entrada e, em seguida, definir em porta pelo valor inicial padrão. Será o nosso valor inicial que passaremos por aqui. Então vamos colocar o valor inicial. Tudo bem, então temos o próprio manipulador de mudanças que precisamos especificar. Então vamos derramar na mudança de entrada. Então normalmente, como você se lembra, ele recebe um objeto de evento. Mas em nosso terno, é um pouco diferente como o primeiro argumento para o evento de mudança. Então, se eu colocar inalterado aqui, se eu passar o mouse sobre ele, você pode ver que o primeiro argumento vai valor. Então, ele é apenas feito para nós para ser mais amigável, então nós vamos ter valor em vez disso, fora de referência até mesmo valor de ponto alvo. Então aqui, vamos colocar também usar chamada de volta porque não teremos qualquer dependência e queremos otimizá-lo com antecedência a partir daqui. Bubble call apenas definir entrada para o seu valor assim. E para estes em mudança, nós vamos derramar sobre a mudança de importação, tudo bem. E também, não se esqueça de associar o valor real com nossa entrada, e estamos quase terminando aqui. Agora, nós também queremos fazer nossa entrada editar ervas. Então vai ser apenas um valor de barras que indicará então vamos criar o seu estado credível é desejável e, por padrão, será definido como falso. Tudo bem, então esta entrada será desativada quando tivermos é credível, definido como falso. Então, quando comestível é tão verdadeiro? Seremos capazes de gerir o nosso inquérito. Então vamos criar botão real que irá indicar que Então vamos pobre grupo de entrada não vai colocar apenas botão porque teremos os dois botões dentro de nossa importação ou fechar ou editar . Então vamos colocar o grupo de entrada para fazer parecer tateado, sabe? Então grupo de entrada no botão e dentro deste botão, vamos colocar eu posso e isso eu vou ser o próximo. Então, se a nossa entrada vai ser comestível, exibição venerável botão fechar. Então, caso contrário, quando vemos a entrada real e não pretendemos editá-la, vamos receber adicionado a Então este é apenas um ícone com, como , lápis, possamos ver que podemos adicioná-lo. Tudo bem, então para isso no botão clique, nós vamos derramar em editar clique e este clique não editado vamos definir aqui. Então, na edição Clique também irá citá-lo ao redor, use chamada de volta com antecedência porque não teremos dependências ou realmente com você. Mas não importa, Corneau. Então vamos colocar Set é credível para reverter o valor do nosso estado atual. Então vamos chamar essa função que irá reverter o valor do boliche. E também queremos ter certeza de que se clicarmos em cancelar, voltaremos ao estado inicial. Então, queremos também chamar set input e apenas no caso, defini-lo de volta para o valor inicial. Então agora ele aparece como uma dependência. Então, vamos colocá-lo aqui. E vamos realmente dizer com e ver o que está acontecendo aqui. Tudo bem, Cool. Então agora nós temos isso assim, e parece quase legal, mas parece que eu sou algo. Oh, sim, na verdade, porque usamos o grupo de entrada, precisamos envolvê-lo em grupo de entrada. Isso é culpa minha. Um grupo tão importante. E eu vou colocar isso no final assim. Agora, vamos dar uma olhada. Tudo bem, agora parece bom. Eu não posso adicionar entrada agora, porque é comestível tal cair. Então, quando eu clicar neste botão agora, eu serei capaz de adicioná-lo. Este botão. E como você pode ver, quando eu clicar neste botão, a função on edit click será disparada. Então, se não temos este valor inicial de entrada conjunto quando eu clicar neste botão, ele não será re definido para o valor padrão. Portanto, queremos ter certeza de que é sempre inicial se cancelarmos. Tudo bem. Então, o que mais precisamos fazer? Precisamos definir outra garrafa que será exibido quando realmente clicar em editar. Então, nós somos capazes de saborear aqui. O que? Nós vamos derramar. Nós vamos derramar. Se a nossa importação é credível, então vamos renderizar outro grupo de entrada inferior. Vamos copiar e colocar aqui. Então, para no clique, vamos colocar no clique seguro. Não vai ser o mesmo em Salve isso. Passamos como um adereço. Vamos definir outro “clique seguro “aqui. Por agora. Que seja assim. Então, para este botão, o que vamos para a sua mudança passiva de fogo. Eu posso, eu posso vai ser um Aiken estático. E isso eu posso é se eu me lembro que é cheque. Vamos dar uma olhada. Tudo bem, vá. Sim, é. Cheque. Parece que temos a marcação. Vamos realmente definir a funcionalidade para clique seguro. Então, o que vamos fazer aqui? Primeiro, vamos fazer uma validação muito primitiva. Primeiro, vamos obter o valor aparado para evitar espaços desnecessários ao redor do nosso texto. Então vamos colocar o valor aparado e ele vai ser guarnição ponto de entrada. OK, então vamos verificar se o nosso valor aparado vai ser apenas um espaço vazio. Então vamos alertar foi pacificado. Mensagem vazia como um adereço. Podemos colocar esta mensagem vazia aqui e vamos adiar quatro segundos. Tudo bem. Então, no final, vamos colocar Set é credível para quedas porque quando clicamos em seguro, queremos torná-lo não credível como era antes. E agora aqui, vamos verificar contra mais um. Acho que vai ser se aparado não vai ser o nosso valor inicial. Então vamos verificar se realmente editamos algo e nosso valor é diferente Onley, então vamos chamar nossa própria chamada segura de volta que especificamos aqui dentro do painel. Então ele vai ser em uma função de pia. Então vamos pacificá-lo, já que ele vai estar enfrentando vai ser uma promessa, então precisamos esperar por ela. Então vamos derramar uma pia e vamos derramar um peso no cofre que passamos aqui. E como você se lembra, este retorno de chamada receberá novos dados como um argumento. Então aqui precisamos passar nossa entrada real. Então vamos pobre não entrada ou talvez aparado para valor, porque não queremos colocá-lo com os espaços apenas desnecessários em torno dele. Tudo bem, então agora vamos verificar. E aqui, vamos vender-nos. Olha, novos dados para ver se realmente funcionou. Agora parece bem acabado. Talvez no futuro vamos ajustá-lo um pouco para atender às nossas necessidades. Mas, por enquanto, parece bom. Vamos abrir o painel. Vamos abrir, Cônsul, e vamos dar uma olhada. Então, agora, se eu editar, se eu cancelar, tudo ficará bem. Então, se eu clicar novamente no cofre, nada muda. E não temos essa ligação de volta no cofre disparado. Então, se eu mudá-lo e se eu salvá-lo agora, eu tenho o novo valor que está sendo Cônsul bloqueado a partir disso no manipulador seguro. Então, na verdade, funcionou. E acho que terminamos aqui no próximo vídeo. Vamos realmente aplicar alguma funcionalidade para este componente, ou talvez em torno deste componente. Então atualizamos nosso apelido riel. Mas, por enquanto, vamos terminar este vídeo e vamos cometer nossas mudanças. Então eu vou colocar criado reutilizável, entrada credível. Tudo bem, Perfeito. Vejo-te no próximo. 109. Criando o painel - Update do usuário (parte 3): Ei, bem-vindo neste vídeo. Vamos continuar construiu nosso painel comestível atualizar nosso apelido real dentro do banco de dados Riel Time. Vamos lá. No último vídeo, criamos entradas credíveis. E nós definimos isso em função segura que passamos para editar a entrada de ervas. Então esta função de retorno de chamada vai receber a nossa entrada final quando clicamos no botão salvar Então vamos agora usar esses dados e atualizar nosso banco de dados. . Então, como antes, vamos usar nosso banco de dados, objeto para acessar banco de dados. Então precisamos escolher pacificar referência ao banco de dados. Então vamos colocar perfis, vamos usar um fio da polícia deles aqui. Vamos colocar o perfil. Não use, eu d. Agora precisamos atualizar apenas o apelido. Não queremos ter criado isso. Então precisamos ser mais precisos quando se trata de fazer referência a algo dentro do banco de dados em tempo real . Então precisamos fazer referência a esse nome aqui. O que podemos fazer, podemos realmente referenciá-lo de duas maneiras. Podemos colocar sua barra aqui e colocar o nome ou eu prefiro outra maneira só de torná-lo, você sabe, mais amigável. Eu colocaria uma criança aqui e aqui. Eu também preciso especificar caminho, mas este caminho será um relativo ao caminho que especificamos dentro da primeira referência. Então vamos empurrar este nome. Então vamos especificar criança fora deste caminho dentro do banco de dados, tudo bem. Ou, na verdade, vamos colocá-lo em um valioso vamos colocá-lo, digamos, nome de usuário Nick, ref. Então vamos definir um bloco try catch porque vamos trabalhar com dados assíncronos e promessas. Então aqui nós vamos derramar, esperar, e então nós simplesmente chamar nome de usuário apelido ralf dot sat, que irá escrever dados para o banco de dados. E aqui vamos colocar novos dados que recebemos como argumento. Depois disso, não vamos Se eu usuário com mensagem de sucesso e vamos dizer apelido tem Bean atualizado e novamente por segundos e para qualquer outro vamos colocar em sua mensagem onde vamos colocar nossa mensagem como seu texto e também quatro segundos. Tudo bem, parece legal. Vamos verificar isso. Vamos navegar de volta para o aplicativo quando eu clicar em editar deixe-me alterar meu apelido para entrar Seja do que eu clique seguro e apelido foi atualizado E se voltarmos para base posterior. Você pode ver que os dados reais são alterados. Vamos tentar mais uma vez. Vamos colocar apenas eu sei e eu clique seguro. O apelido foi atualizado. O banco de dados é atualizado. Tudo parecia bem longe. Se ainda tiver uma pergunta. Por que exatamente isso? Andy sendo atualizado quando atualizarmos os dados dentro do banco de dados. Mais uma vez para explicações. Dentro do contexto de nosso provedor, usamos assinaturas, ouvintes em tempo real para nossos dados. Então, para usar uma referência, que é o nosso caminho de banco de dados sob perfis, usuário I d. Colocamos ouvinte em tempo real estes chamada de volta. Então este frio é disparado toda vez que algo muda sob este caminho dentro do banco de dados. Então, se digamos que o nome muda sob o usuário I d que estes chamada volta será disparado e vamos atualizar o estado do perfil com este objeto de dados, que será novo no momento em que estes Colback é disparado. Assim, o mesmo se aplica para criado em ou para qualquer outro preenchido. Então, se tivéssemos algo como a idade aqui, e se a idade foi mudada, então esses Colback serão demitidos e então um certo, eu acho que tudo bem. E você entendeu. Agora vamos confirmar nossas mudanças e terminar o vídeo. Então vamos começar bem em tudo. Então vamos colocar Pete cometer, digamos que apelido atualizado dentro do banco de dados. Tudo bem. Parece bom. Vejo você na próxima. 110. Criando o painel - provedores de hiperligação (parte 4): Ei, neste vídeo, vamos continuar construindo o componente aeroportuário e vamos associar conta de usuário com vários provedores de assinatura ou vários métodos Sinan. Então, por exemplo, se eu me conectar ou se eu olhar com o Facebook e, em seguida, se eu olhar para fora e olhar para dentro com o Google, eu acabo na mesma conta. Não vou ter duas contas diferentes. Tudo bem, então vamos fazer isso. Primeiro, vamos voltar ao nosso código. E aqui no painel, vamos criar seu arquivo, que vamos nomear Provider Block por enquanto. Deixe-o ser um componente vazio e vamos editar para o nosso painel dentro Index GS logo após Hey Profile Name provedor Block. Perfeito. Agora, para continuar, precisamos saber como podemos realmente acessar nossos dados de usuário atuais onde dados de objeto de usuário para ser mais específico. Então, em vez de usar nosso gancho de perfil de uso para obter os dados, podemos realmente usar fora do objeto, e então podemos acessar o usuário atual. Então vamos bater nele e ver o que você recebe? Então, se eu agora ir para esse quadro, se eu olhar dentro do Cônsul agora, eu tenho o objeto de usuário desligado atualmente usuário conectado, então ele é gerenciado pela base de fogo. Aqui restringimos diferentes tokens de acesso, tokens de atualização, nome de exibição, e-mail e outros dados. Mas estamos interessados agora em dados de provedores que temos aqui. Então, é basicamente um array off provedores ou array off Simon métodos que estamos usando agora. Então, como você pode ver, agora, nós temos apenas um elemento, que é google dot com. Então, vamos usar essa informação para exibir que estamos conectados no momento não foram a este provedor específico. E a coisa é que, se você se lembrar, colocamos ouvintes em tempo real para nossos dados de perfil. Então, sempre que atualizamos algo, ele é atualizado em todos os lugares com os provedores. Ele não funciona em tempo real, então precisamos gerenciá-lo usando estado de reação. Então, tudo bem, vamos voltar ao bloco de provedores. E aqui vamos definir um novo estado, que vamos nomear está conectado, e não vai ser um valor de boliche. Será um objeto que indicará se estamos conectados ao Facebook ou ao Google. Então vamos ter um objeto com duas chaves, google dot com e facebook dot com, que é Provider i d pode ser encontrado que dentro desta matriz, assim como você pode ver para o Google, é google dot com. Certo, então para o Google Dot com, vamos verificar se estamos conectados. Então vamos acessar os dados atuais do provedor de pontos do usuário. Então é uma matriz, e na chuva, podemos aplicar alguns para verificar se algum elemento é realmente justifica a condição. Então vamos ter aqui nossos dados, e vamos verificar se alguns dos nossos elementos de matriz onde tem provedor I D ou google dot com. Se provedor de dados I d é igual google dot com e o mesmo que faremos para o Facebook. Então vamos copiá-lo. E vamos substituir google dot com pelo facebook dot com. Tudo bem, bom. Desta forma, agora teremos disponível está conectado. Isso indicará o que estamos conectados ao Google ou Facebook. Agora vamos realmente definir o nosso marcador. Então, dentro desta definição, vamos derramar nossos botões ou ataques que irão indicá-lo. E aqui teremos uma carga off renderização condicional. Mas, por enquanto, escute. Desafio, marcação estética. Então, primeiro vai ser elemento preso. Assim, o elemento pilha será perto, herbal, e terá cor verde porque vai ser quatro Google dentro, teremos Aiken. E isso eu posso ter eu posso fora do Google e ele vai dizer conectado. Tudo bem. E também agora temos esta manhã. Vamos colocá-lo aqui no topo da mesma forma. Vamos nos candidatar ao Facebook. Então vamos copiá-lo. E vamos substituir a cor pelo azul e eu posso pelo Facebook. Tudo bem. Parece bom. Agora vamos dar uma olhada. Se formos ao painel agora, estamos conectados. Então isso será exibido quando estivermos realmente conectados aos nossos provedores. Tudo bem, então vamos definir outras coisas que serão nossos botões para realmente se conectar a estes ou àqueles provedores. Então vamos colocar um pouco fora, fundir neste bloco, e então vamos definir nossos fundos. Então o primeiro botão vai ser para o Google. Então vai ser um elemento de bloco. Ele terá cor verde e dentro novamente. Vamos ver e eu venho e eu posso ser, Digamos, também Google e vamos nomear X ligado ao Google. O mesmo será para o Facebook. Vamos copiá-lo. E vamos substituir a cor pelo Lynn azul para o Facebook. E eu posso vai ser Facebook. Tudo bem, vamos verificar. Tudo bem. Parece bom. Então, vamos ter isso para botões de fundo para realmente se conectar ao provedor. E esses dois no dizer as pessoas têm quando estamos conectados. Tudo bem. Então vamos primeiro derramar nossa renderização condicional para o caso quando já estamos conectados. Então, para essas tags, vamos colocar se está conectado, então, porque é um objeto, podemos acessar suas propriedades. Então, se eu estiver conectado ao Google Dot com no Lee, então eu vou renderizar este elemento tag e o mesmo, na verdade, vamos fazer para o Facebook. Então agora teremos um exibido em Lee quando estivermos conectados. Tudo bem. Parece bom. E para esses botões, aplicaremos o próximo. Então, se não estamos conectados ao Google que vêm, então vamos exibir este botão e o mesmo vai fazer quatro facebook. Então, se não estamos conectados ao seu Facebook, então vamos exibir esse tipo de botão. Tudo bem, vamos verificar. Se eu abrir meu painel, estou conectado ao Google e não estou conectado ao Facebook. Tudo bem, então agora a coisa é realmente fazer alguma funcionalidade para aplicar tudo com um estado. Certo, então primeiro precisamos definir os manipuladores. Então teremos no total para manipuladores, para manipuladores para UNL Inc do Google e Facebook, e dois manipuladores para um link para Facebook e Google. Então vamos defini-los primeiro vai estar em um link no link Facebook como este. Então teremos o Google desvinculado. Então teremos vinculado Facebook e LinkedIn Google e vincular Google assim. Tudo bem, primeiro, vamos talvez fazer a funcionalidade desvinculada, então será o mesmo, e é muito fácil de fazer. Então nós vamos criar outra, como, como, uma função comum que nós vamos chamar dentro do link Facebook e permitir que o Google que nós vamos chamar, você sabe, apenas no link, e então nós vai receber aqui provedor I d provedor. Eu gostava disto. Certo, então vamos chamar isso de desvinculado do Facebook desvinculado assim, e então colocaremos Facebook Dot com e o mesmo que faremos pela Gogol. Vamos colocar no link google dot com assim. Tudo bem, então você desvinculou o provedor de verdade. Vamos fazer a próxima coisa que vamos colocar primeiro try, catch block, e vamos perguntar em primeiro lugar se apenas um método de login é deixado para o usuário. Por isso, é possível que nós desvinculados do Google, e então acabamos com nenhum provedor de login em tudo dessa maneira, conta será abandonada e não terá qualquer método de login, então isso significa que será tipo de isso. Por isso, queremos evitar isso. E vamos verificar se o comprimento do ponto de dados do provedor do ponto do usuário atual do ponto é igual a um. E queríamos conectá-la. Então, temos apenas um método de login e clicamos em desvinculados. Vamos receber um aviso. Vamos lançar um novo editor, e nós vamos dizer que você não pode desconectar para, um provedor I d. que nós recebemos como um argumento aqui. E agora vamos pegar esse assunto que jogamos aqui, e vamos colocá-lo alerta e editor de arte, vamos dizer melhor mensagem por quatro segundos. Tudo bem, então se tudo está bem aqui e se temos, digamos, provedores conectados e queremos nos desconectar de um deles, é seguro. Então nós vamos cancelar ponto usuário atual ponto unlinked este método, se eu chamá-lo, você pode ver em links um provedor de conta de usuário e eu preciso passar provedor I D, que vai ser provedor I d de nossos argumentos. Então é uma promessa o que vamos fazer, vamos esperar. E porque é um pensamento aguarda índice, precisamos colocar um canto na frente da função. Então, depois que esperamos, precisamos atualizar nosso conjunto está conectado. Precisamos atualizar nosso estado local. Então, o que podemos fazer? Nós podemos realmente criar outra função apenas para atualizar o nosso estado para que possamos chamá-lo algo como esta atualização está conectada, e dentro podemos passar provedor I d e, em seguida, apenas valor se é verdadeiro ou cai. Então, aqui, provedor de relatório i d. E quando desvinculamos, queremos configurá-lo para forçar. Então vamos criar esta atualização está conectada vamos receber provedor I d. como um argumento. E então nós vamos receber realmente, o valor, algo assim. Então, dentro desta função que vamos chamar conjunto está conectado aqui, vamos receber valor anterior dentro do callback. E aqui precisamos retornar e você valoriza porque é um objeto. Queremos ter certeza de que mantemos a estrutura. Então, vamos voltar. Certo, vamos colocar mais explicitamente a partir desta semana de retorno e Alba Jet aqui, vamos fundir o estado anterior assim e depois atualizar o provedor real. Precisamos abrir esse tipo de parênteses. Então precisamos citar provedor I d como uma chave e, em seguida, revela pacificar o valor. Tudo bem, então desta forma, ele irá atualizar o objeto com o especificado de qualquer i d e valor. Tudo bem. Bom. Parece muito bem. Vamos talvez também, e outro alerta aqui com alerta, talvez apenas informações, e vamos dizer, desconectado do provedor desconectado do provedor eu d como este a menos que coloque quatro segundos aqui . Tudo bem. Agora, vamos realmente vincular esses manipuladores aos nossos botões, então precisamos desvincular o Facebook. Precisamos colocá-lo aqui para o elemento saco. Então aqui podemos ter isso em um evento próximo. Então, para este evento unclos, mastigável especificar no link Google, na verdade, eo mesmo para o Facebook. Então aqui vamos vestir roupas e vamos colocar no link Facebook desta vez. Tudo bem. Agora ele tem funcionalidade suficiente para testá-lo. Então vamos abrir o painel. Vamos clicar neste elemento próximo. Então, quando clicamos nele, você não pode desconectar do google dot com que porque nós só temos o método de assinatura Google apenas um deles. Então, se desconectarmos dele, vamos fazer nossa conta que tudo certo para ir agora é realmente e nossa funcionalidade de link . Então, novamente , será o mesmo quase o mesmo. Então vamos criar uma função comum como UNL Inc. Então vamos colocá-lo, talvez aqui e vamos nomeá-lo. Vamos ligar. Tudo bem, Então ele vai receber não um provedor i d. Mas o objeto provedor o mesmo que usamos dentro. Página de login. Vamos ver este novo provedor firebase Auth firebase. Tudo bem, então eu copiei. Então deixe-me comentar. E aqui vamos ligar para este link e depois assinamos. Precisamos passar objeto provedor que receberemos como um argumento. Então, para o Facebook, vamos chamar a nova base de fogo fora do provedor do Facebook. Vamos primeiro importar a base de fogo da base de fogo. Tudo bem, olha, o treinador e o mesmo vão fazer para Link Google. Então vamos copiá-lo. E aqui vamos chamar o provedor Google Auth. Tudo bem, parece bom. Agora vamos associar esses manipuladores com antecedência aos nossos botões. Então, no clique, vamos vincular o Google E para este botão clique em um link Facebook. Tudo bem. Parece bom. Então, agora qual será a nossa estratégia? Então é realmente muito, muito simples com base de fogo novamente, precisamos usar nosso objeto auth. E aqui vamos chamar o nosso usuário atual e, em seguida, ligar com link pop-up com pop-up. Precisamos especificar apenas o objeto provedor que recebemos como um argumento que vai ser um desses, tudo bem. Por isso, mais uma vez, é uma promessa que temos de esperar. E depois que ele é atualizado com sucesso, o que é convertido para você função de corrida depois que ele é atualizado com sucesso, vamos notificar os usuários com alerta em quatro. Digamos conectados ou talvez ligados dois. Provedor. Vamos usar a preparação do Rincon. E porque ele está no objeto provedor. Desta vez este objeto provedor tem provedor I d como sua chave. E, novamente, especificaremos quatro segundos no caso de qualquer outro. Vamos colocar alerta na mensagem dela e colocaremos nossa mensagem aqui assim. E no final do dia, precisamos também atualizar nosso estado local. Então vamos chamar o mesmo que antes da atualização estar conectada. E desta vez vamos puxar provedor ponto provedor I D. E então nós vamos colocar a verdade porque nós ligamos nossa conta. Tudo bem agora, parece bem. Vamos verificar isso. Parece que temos todas as funcionalidades. Deixe-me checar duas vezes. Ok, parece bom. Agora vamos para o painel. Se eu clicar no link para o Facebook, vamos ver o que vai acontecer agora. Serei solicitado a olhar para o meu busto do Facebook porque eu já fiz login. Agora eu tenho ligado ao Facebook. Se eu for para autenticação e se eu tiver um novo, posso ver que eu tenho que entrar provedores associados a esse usuário. Então funcionou mesmo. Agora, se eu Vamos um clique em Desconectar do Facebook Agora, Eu desconectei do Facebook dot com. Se eu clicar no Google, você não pode se desconectar do Google porque ele é o único que resta. E se eu atualizar novamente, você pode ver o Facebook desaparecer. Então, na verdade, tudo funciona. Tudo bem, então foi muito, na verdade, acho que é a boa hora para terminar este vídeo. Então, vamos adicionar tudo ao estado do palco, e então vamos vincular o Facebook e o Google a um provedor criado pela conta Block Who? Muito bem, vemo-nos na próxima. 111. Criando o painel - criando o Avatar (parte 5): Ei, neste vídeo, vamos continuar a construir o painel, e vamos começar nossa gestão com avatares de perfil de usuário. Assim, neste vídeo vamos criar um botão e podemos selecionar uma imagem do nosso PC que então vamos fazer upload para a base de fogo e usar como nossa imagem de avatar. Vamos lá. Então, primeiro, vamos criar um novo arquivo em seu painel. Esse nome problemático de um carro aplaude Bt. Então vamos criar um componente vazio. Por enquanto, vamos colocar Olá dentro do que no Index GS, que é o nosso painel logo após a entrada comestível. Vamos fazer referência ao upload de Bt do avatar assim. Ok, bom. Agora vamos começar a construir nosso componente. Então o nosso elemento superior vai ser um desenvolvimento para o nome da classe. Vamos dar-lhe um pouco fora de margem na costeleta, que vai estar vazio três. E depois queremos manter tudo centrado. É por isso que colocamos o centro fiscal. Tudo bem, então nós precisamos especificar entrada fora do tipo de arquivo, mas nós não queremos usar o nativo porque ele não parece o melhor caminho. Então, por enquanto, vamos apenas mantê-lo como texto e talvez se você quiser, você pode mudá-lo. Para fazer isso. Precisamos colocar um dif aqui. Então vamos especificar o insight do rótulo. E dentro deste rótulo, vamos colocar um novo Avatar selecionado e também ao lado deste texto dentro do rótulo. Nós vamos colocar em adiar o tipo de arquivo, mas nós vamos dar a ele exibição fora nenhum. Então, na verdade, clicamos neste texto. No entanto, ao mesmo tempo, clicamos nesta entrada. Então vamos despejar na porta fora do tipo de arquivo assim. E também, vamos dar o nome da classe fora, exibir nenhum. E temos este aviso no rótulo dizendo que ele deve ser associado com o controle. Então, para esta entrada, vamos definir uma idéia algo como Al Atar upload. E vamos dar essa idéia para html quatro para dis label. Então HTM de quatro vai ser avatar. Aplaudir. Tudo bem. Também para esta gravadora, vamos dar o nome da turma deste bloco de jogos. Além disso, ele vai ser ponteiro mais grosseiro, e ele vai ser um pouco acolchoado como este. Tudo bem, vamos verificar. Agora. Se eu for ao painel , fica bonito. Agora temos este botão. Então, quando clicamos nele, podemos realmente selecionar arquivos. Vamos fazer desta forma que podemos selecionar apenas imagens por aqui. Então, para esta entrada, vamos colocar outro prop, que é, exceto e ele vai ser uma string fora de tipos de arquivos aceitos. Mas vamos especificar esses tipos de arquivo fora do componente. Então, no futuro, é mais fácil navegar dentro desse componente. Vamos amarrar tipos de importação de arquivos, e ele vai ser como beber fora tipos de arquivos referenciados por vírgula. Então primeiro vamos aceitar arquivos PNG do que arquivos J PAC e também J pack off off esta extensão. Tudo bem, então para isso exceto prop, vamos passar tipos de importação de arquivos e estamos prontos para ir Agora vamos conferir. Se clicarmos aqui, podemos ver os arquivos P e G e J de volta. Tudo bem. Parece bom. Agora, qual será o nosso próximo passo? Então, quando selecionamos uma imagem, queremos que um novo modelo seja aberto, e dentro deste mortal, vamos ver a pré-visualização. Então precisamos definir o motor de Indo. Então aqui, ao lado do rótulo vamos usar o elemento modelo do nosso terno. E dentro deste modelo, vamos colocar o modelo ponto Heather do que ao lado dele. Teremos corpo e também rodapé como este. Então, para o modelo, precisamos especificar show propriedade. É um marcador que indica se ele está aberto ou não do que no manipulador de altura quando este modelo está fechado. Então precisamos usar nosso próprio costume. Espero que criamos anteriormente usar estado mortal para realmente obter esses valores. Então, vamos importá-lo. E vamos D estrutura é aberta, aberta e próxima. Então, para no evento altura, vamos chamar Close Handler e para o show vamos especificar está aberto. Então dentro de Moto Heather, nós estamos indo para port model dot title Então este título vai ser um justo e aplaudir Talvez assim, aplaudir novo avatar e vamos remover este título na parte inferior aqui. Em seguida, dentro do corpo. Vamos especificar outra coisa. E dentro do rodapé, vamos colocar um fundo que vai realmente carregar o nosso avatar. Então vamos digitar aplaudir Novo Avatar e para esses botões irá especificar a aparência. Vamos dizer fantasma, e também vamos dar-lhe com off 100 especificando que ele vai ser um elemento de bloco . Tudo bem, então agora, como você pode ver, nós não temos nenhum gatilho para realmente abrir nossa moto. Precisamos determinar de alguma forma quando selecionamos o arquivo. Então, para isso, vamos usar no evento de alteração disponível na importação fora do arquivo tipo. Então vamos pacificar a própria mudança. E para esta mudança, vamos criar uma função que vamos nomear na mudança de entrada de arquivo. Tudo bem, agora, vamos criar aqui no topo e esta função porque é um manipulador para um evento. Esta função recebe um objeto de evento. Tudo bem, então este objeto de evento terá alvo e sob alvo. Podemos acessar arquivos reais que selecionamos, e sempre vem como uma matriz fora de arquivos. Então vamos colocar arquivos atuais em até mesmo arquivos de destino. Então, uma vez que será sempre uma matriz, precisamos verificar se selecionamos apenas um arquivo. Então vamos verificar. Se arquivos atuais desse tamanho é igual a um, então nós vamos aplicar nossa lógica. Então vamos primeiro pegar nosso primeiro elemento da matriz. Então vamos colocar arquivo, e vamos colocar arquivos atuais e referenciar o primeiro elemento. Então precisamos realmente verificar se o arquivo que selecionamos é o arquivo válido, porque não importa o que especificamos. Por aqui. Eu posso procurar qualquer arquivo e mudá-lo para todos os arquivos, e então eu posso comprar Maio bife upload, digamos adjacente. Então queremos verificar se este arquivo é realmente uma imagem. Então, aqui no topo, vamos especificar tipos médios que são acessíveis por nós. Para isso, vamos especificar qualquer tipo de arquivo disponível, digamos, aceito. Então, aqui nós estávamos indo para especificar um array fora de strings. Então, primeiro, nosso tipo de feixe vai ser imagem barra p e G. Então vamos ter imagem barra j pack. Então, se eu não estiver errado, é o correto. E também vamos ter imagem barra p j pack. Tudo bem, Bom. Agora precisamos criar uma função auxiliar que irá verificar se este arquivo satisfaz matriz fora tipos médios. Então, se o nosso tipo de arquivo é um deles, então nós estamos indo para criar uma nova função auxiliar que irá nomear é arquivo válido e ele vai receber arquivo como um argumento, e ele vai verificar o tipo de arquivo contra esses valores. Então, vamos simplesmente verificar tipos de arquivos aceitos Inclui tipo filhinho de arquivo. Tudo bem, então ele retornará um valor booleano. Tudo bem, agora aqui, para dentro. Ah, eram manipuladores. Podemos perguntar se vamos perguntar se é válido, arquivar nosso arquivo, então vamos fazer algo. Caso contrário, vamos mostrar um erro ao usuário que. Oh, garoto, você selecionou a hora errada do arquivo. Então vamos colocar alerta. Então vamos colocar aviso, não um erro, e nós vamos especificar, talvez tipo de arquivo errado, e então vamos pobre tipo filha de arquivo como este, e vamos especificar quatro segundos. Tudo bem, então o que vamos fazer quando tivermos o arquivo válido? Primeiro de tudo, vamos abrir nossa janela móvel. Mas antes de abrirmos, precisamos de alguma forma definir a nossa imagem que aplaudimos. Então, para isso, vamos criar um novo estado. Então vamos criar um novo estado com estado de uso, que vamos nomear. Digamos apenas imagem e imagem definida por padrão. Será ajustado para agora. Mas quando temos desenvolvido imagem selecionada. Vamos chamar Set Image, e vamos colocar arquivo como nosso estado assim. Tudo bem, agora, vamos verificar. Então, se eu for para o painel, se eu selecionar um novo avatar, se eu carregar uma imagem, tudo bem, Motile abre. Agora, vamos fazer a mesma coisa. Mas vamos selecionar o arquivo Jason. Se eu clicar em abrir, tenho aplicativo de tipo de arquivo errado, Jason. Então funcionou mesmo. Tudo bem? Agora, qual será o nosso próximo passo? Nosso próximo passo é mostrar a visualização e ajustar a imagem. Então, como somos capazes de fazer isso, vamos usar reagir pacote editor avatar que vem de um PM Eu realmente gosto deste mini pacote. Isso nos dá a oportunidade de personalizar a imagem carregada. Nós não vamos mergulhar em muitos detalhes, mas nós apenas podemos dimensionar nossa imagem para precisar do tamanho dela. Então, primeiro, vamos instalá-lo. Então eu vou abrir meu terminal e a partir daqui, que eu tenho outro Tudo bem, tudo bem. Vou instalar o Avatar React, editor e vamos esperar até que seja instalado ou certo. Parece que o nosso pacote foi instalado. Vamos executar novamente o AP e P. M Run, começar e vamos ver como podemos realmente usar este pacote. Então deixe-me copiar o comando de importação. Deixe-me colocá-la aqui no topo. E como você pode ver, eu preciso usar este componente assim. Então vamos copiar isto. Vamos copiar este componente do que dentro do nosso código para o corpo do modelo. Vamos especificar este componente, mas primeiro, vamos verificar se temos nossa imagem definida dentro do estado. Então, vamos má imagem. Se tivermos imagem, vamos exibir isso sobre nosso componente editor e para imagem. Nós vamos especificar nosso arquivo que temos estado EUA para With e Height Mobile limitado a 200. Então, para a fronteira, vamos colocar, digamos, apenas 10. E esta é a borda por bordas do que não precisamos de cor. Não precisamos de escala, mas precisamos de um raio de fronteira. Queremos fazer circular. Então vamos especificar os rádios de fronteira 100. Tudo bem, agora, vamos verificar. Se eu atualizar a página que eu clicar no modelo Selecione novo Avatar. Se eu clicar neste carro e abrir agora, eu posso ver que eu tenho este elemento Converse, que é este pacote. E agora eu sou capaz de adicionar a minha imagem um pouco. Tudo bem, então parece bom, mas não está no centro. Isso significa que precisamos adicionar mercado adicional para esta imagem para este editor de avatar. Vamos colocar outra definição em torno dele assim. E para esta definição. Vamos especificar display flex. Então vamos colocar o display flex. Justifique, digamos, centralize, alinhe o centro de itens e vamos colocá-lo em altura total assim. Agora, se eu tivesse um fresco, vamos dar uma olhada. Deixe-me selecionar uma imagem novamente. Mas ainda assim, não parece bom porque não é justificado. Centro. É um centro de conteúdo justificado. Agora, deixe-me tentar. Selecione Novo Avatar. Tudo bem, agora parece bom. Está centrado. Ok, então eu acho que este é o fim para este vídeo, e nosso próximo passo será realmente carregar a imagem. Mas ele vai ser o tópico para o nosso próximo vídeo sobre este passo. Vamos confirmar nossas mudanças e terminar este vídeo. Então nós vamos adicionar tudo a este estado de estágio que nós vamos obter commit, e nós vamos colocar vamos dizer, começou a trabalhar com avatar usuário. Aplaudir. Tudo bem. Parece bom. Vejo-te no próximo. 112. Criando o painel - Uploading do Avatar para o Firebase (parte 6): Ei, neste vídeo, vamos continuar a trabalhar no upload de avatar entre componentes, e vamos terminar o upload de que sera waters. Vamos lá. A primeira coisa questionou você ia definir um manipulador para um evento de clique para aplaudir seu botão de avatar. Então vamos pacificar no evento clique e vamos criar uma nova função que vamos nomear no upload . Clique. Em seguida, vamos colocar este manipulador logo após a alteração de importação de arquivo, e agora precisamos de alguma forma obter acesso à imagem real. Desta vez, esta imagem é editada. Então precisamos ter acesso a esse elemento de conversa. Então, se nós inspecioná-lo, é um converse dentro Dom porque é sobre o nosso componente editor que usamos a partir do pacote. Tudo bem, então, para entender o que está realmente acontecendo, como podemos obter a imagem que precisamos para navegar para a documentação deles, do que se rolarmos para baixo , limitamos um exemplo acessando a imagem resultante. Aqui confinamos este método obter imagem escalada para conversar. Mas como podemos ver a partir deste exemplo, ele usa componente baseado em classe, e também usa algo chamado referências. Então referências em reagir é a maneira de acessar elementos Dom diretamente ou reagir diretamente elementos onde mais apropriadamente seria dizer programaticamente. Então vamos descobrir como podemos realmente colocar uma referência em nosso componente editor avatar dentro de um componente baseado em função. Então, primeiro, precisamos importar um gancho que não vimos antes de reagir, que é usado ref, que significa referência de uso. Agora precisamos criar uma nova referência, e vamos nomear este gráfico editor de avatar de referência, e vamos chamar este gancho assim. Agora, precisamos passar esta referência para este componente. Então nós vamos especificar Rafa, e então vamos derramar editor avatar áspero. Então agora nós somos capazes de acessar este, digamos, avatar, componente editor usando esta referência, que é nossa água eu fiz muito áspera. Então, clique no upload. Vamos colocar Vamos dar uma olhada. Temos de aceder a este editor. Obtenha habilidade de imagem para examinar para acessar o valor real fora desta referência. Precisamos colocar o próximo, então vamos colocar o converse, e vamos dizer que vamos acessar Avatar Edita Ralf dot current. Portanto, é elemento atual fora desta referência porque também pode ser indefinido. Então nós nos certificamos de que acessamos o elemento atual. Então, em seguida, podemos acessar o método real, que vai ser obter imagem escalada, duas câmeras. Então, vamos chamá-lo. E agora podemos realmente ter o nosso elemento de conversa. Mas a coisa é que não podemos trabalhar com a conversa. Não podemos enviá-lo. Não podemos fazer nada com isso. Então primeiro precisamos convertê-lo para algum antigo que possamos aplaudir para fogo base para que possamos realmente converter Converse em um arquivo blob. E um arquivo de cara é apenas um pedaço fora do arquivo representado em formato binário. Então, usando este formato, podemos aplaudir. Então, em cada elemento inverso, temos este método que é chamado para bloquear, ea coisa com isso para bloquear método que ele só aceitar callbacks. Não podemos usar promessas. Então, para isso, eu quero converter este método baseado em Colback para uma promessa. Então, para fazer isso, vamos fazer o próximo aqui no topo. Nós estamos indo para definir uma nova função que vamos nomear get bloco, e esta função vai receber uma conversa como esta e esta função vai retornar e você promete objeto. Então vamos colocar o retorno novo, eu prometo. Então, não vimos isso antes. Então, para criar uma promessa real, precisamos colocar uma visão de retorno de chamada que recebe dois argumentos, resultado e rejeição. Então vamos chamar esse método para realmente resolver ou rejeitar a promessa. Então, aqui dentro, o que vamos fazer? Vamos chamar Converse para Bluff. Então vamos especificar esta chamada de volta com o resultado que será o blefe real. E dentro deste frio atrás, vamos verificar. Se o nosso sangue existir e tudo estiver bem, então vamos resultar desta promessa que vamos resolvê-lo. Então resultado e valor vai ser o verdadeiro conselho de explosão. Se não temos quaisquer elementos de bloco estavam indo para rejeitar com novo erro e para mensagem de erro , vamos dizer de algo como protestos de arquivo nunca. Tudo bem, então usando desta maneira agora, nós convertemos um método frio e baseado em volta em uma promessa. Então agora podemos usar isso explodir e o que podemos fazer, vamos colocar para tentar pegar o bloco aqui e agora o que vamos fazer vamos chamar isso explodir assim. Então vamos colocar lona lá dentro. E porque é uma promessa, agora precisamos esperar. E no caso de termos algum erro, será apanhado por estes quarteirões aqui. Então, porque usamos aguarda, Index, precisamos converter esta função para qualquer função. Tudo bem, então o resultado será nossa explosão que podemos aplaudir ao armazenamento de arquivos agora sobre armazenamento . Como podemos fazer isso. Ainda não enviamos nada. Bem, vamos voltar para Firebase Doggy S. E aqui, vamos importar outra biblioteca do Firebase. Desta vez ele vai ser firebase barra armazenamento agora para realmente acessar o armazenamento exatamente da mesma maneira que estamos indo para exportar, const armazenamento app ponto tudo bem. E a torta de armazenamento A é muito semelhante ao armazenamento de banco de dados. Precisamos especificar a referência que é realmente o caminho para o arquivo, e então precisamos aplaudi-lo. Então, agora aqui. Primeiro, vamos especificar o caminho sob o qual vamos armazenar nossa imagem. Vai ser, digamos, digamos referência de arquivo avatar como este para que nós íamos acessar nosso objeto de armazenamento de diversos firebase. Então vamos colocar Dot e então vamos chamar a referência. Então vamos armazenar nossos arquivos no passado deles, que é perfil de barra barra usuário I d. Então precisamos levá-lo lá. Eu d Então vamos usar gancho perfil, Então const perfil, vamos começar a partir de perfil de uso. Então nós vamos especificar o perfil dot seu i d e vamos convertê-lo para interpolação de cordas . E então, na verdade, vamos acessar criança e criança vai ser avatar. Certo, então o que estamos fazendo aqui, nós realmente especificamos esse caminho dentro do nosso armazenamento, então ele representará nossa pasta e essa criança será um arquivo chamado Avatar. Nós não vamos colocar qualquer extensão porque ele será automaticamente apanhado pela base de fogo. Tudo bem, agora, próxima coisa balbuciou, você vai realmente carregar o arquivo. Então vamos colocar resultado const upload avatar. Então vamos colocar um arquivo de avatar de peso que Arraf dot colocou. E, em seguida, se o chamarmos, podemos ver que podemos realmente colocar ou blob ou matriz de buffer. Então vamos realmente colocar nosso blub aqui, e então vamos também segundo argumento. Podemos especificar metadados. Então, para dados de matéria, vamos especificar cabeçalho de controle de caixa. Então nós podemos realmente descontar nossas imagens dentro do navegador. Então vamos colocar um controle de dinheiro. E para controle de dinheiro, vamos especificar público que Marx Age. Vamos para a porta 3600, o que representa uma hora em segundos. Então vamos multiplicar por 24 para obter o valor real de um dia, e então vamos multiplicar por três. Então agora temos marcas de idade fora. Três dias especificados em segundos. Tudo bem, então agora que temos ah, Petar, resultado do upload deixe-me remover esta coluna Sammy daqui. Agora que temos um resultado de avatar Plourde, precisamos obter o Não carregue seu l do nosso arquivo para que possamos salvá-lo em nosso banco de dados. Então aqui vamos colocar um download constante, Ural. Então vamos fazer upload da nossa referência de ponto de resultado de água. Não se engane, e não ligue diretamente para baixar o seu l Porque, como você pode ver, é obsoleto ID para usar referência que obter não carregar euro. Então vamos ligar para o Ralf, e só depois vamos ligar. Não carregue euro. Retorna uma promessa. Então vamos esperar por isso. E agora podemos realmente armazená-lo lá dentro. Nosso banco de dados permite avatar usuário pobre Raff que irá representar nossa referência dentro do banco de dados em tempo real . Então, qual vai ser o banco de dados Daut Ralf do que vai ser? Perfis cortam o perfil e depois vamos colocar o filho de um carro. E agora vamos chamar o usuário Avatar Raff, definir, não carregar euro. E logo depois disso, vamos chamar informações de alerta de um carro que foi aplaudido. E vamos colocar quatro segundos. E no caso de qualquer editor, vamos alertar o que quer que seja e diremos nossa mensagem com quatro segundos também. E também antes de salvarmos este arquivo, vamos realmente especificar o estado de carregamento também. Então aqui nós vamos simplesmente criar está carregando e definir está carregando que por padrão, será definido o seu falso. Então, quando realizamos todas as operações logo antes disso, chamamos set está carregando para true. E então quando terminamos, chamamos set is loading to false E no caso de falharmos, também chamamos Set is loading to false agora quando realmente o usamos, nós realmente usá-lo para este botão para torná-lo desativado. Então desabilitado será somente quando tivermos o estado de carregamento habilitado. Tudo bem, então foi muito. Agora, vamos realmente testá-lo. Então deixe-me atualizar a página. Deixe-me abrir, painel. Deixe-me selecionar Novo Avatar. Agora vou clicar neste carro. Vou clicar em Aplaudir novo Avatar, e posso ver que Avatar foi aplaudido. Muito bem, agora vamos primeiro verificar dentro da nossa base de dados. Parece que agora temos um avatar aqui. Como podem ver agora, temos esse público que está doente, que leva ao armazenamento da base de fogo. Vamos verificar isso. O nosso armazém. E aqui podemos ver uma pasta. Vamos clicar nele. Então temos o usuário I d. e dentro temos o arquivo Avatar. Então, quando clicamos nele, você pode ver que temos este seu l que podemos clicar, e ele vai nos abrir a imagem em você toque. Mas a coisa é que agora nós carregamos com sucesso o arquivo para o armazenamento base de fogo. Certo, então agora como podemos exibir essa imagem? Bem, eu acho que este é o tópico para o nosso próximo vídeo, porque agora ele está ficando muito longo. Tudo bem, então vamos salvar tudo para obter o sistema. Vamos chegar nossas mudanças e digamos que o Avatar do Usuário foi carregado. Muito bem, vemo-nos na próxima. 113. Criando o painel - início de Avatar do usuário (parte 7): Ei, neste vídeo, vamos exibir a imagem do avatar enviada dentro do nosso painel. Vamos lá. Primeiro, quero mostrar o componente do nosso traje, que é alcatrão de Alá. Então eu navegou para sua documentação, e eu abri Alit estão sob exibição de dados. Então aqui a coisa legal sobre este componente que ele pode realmente mostrar as iniciais de nome se não tivermos nenhuma imagem. Então vamos abrir um exemplo. E vamos ver como podemos realmente colocar as iniciais de nome se não tivermos nenhum arquivo fonte. Então precisamos simplesmente passar essas iniciais para Avatar Component. Então, o que eu propus fazer, eu propus criar um wrapper em torno deste componente. Então, sempre que não tivermos uma imagem rebelde, as iniciais de nome de exibição. Então, sob componentes, vamos criar novo arquivo, que vamos nomear perfil Avatar. Então deixe ser um componente que retorna este Ah, o que é componente que vem do nosso terno assim? Então, quais adereços devemos especificar para esses Avatar? Então vamos precisar do nome fora do usuário, então vamos passá-lo como adereços. Então vamos nome do destruidor e o que quer que vá para esses componentes, ele será redirecionado para o componente avatar de nossa série. Então vamos colocar, Teoh Avatar adereços. E então vamos espalhá-lo por todo o elemento. Tudo bem, Bom. Agora, dentro deste avatar, precisamos portar as iniciais de nome. Mas digamos que nosso nome é algo como Andrew, e algo vai depois. Então, como podemos obter as iniciais de nome real vamos criar uma função auxiliar. Então vamos deletar isso. E sob MISC, vamos criar um novo arquivo que vamos chamar ajudantes cãozinho e hittable definir todas as nossas funções razoáveis que nos ajudarão durante o código. Então vamos criar uma nova função que vamos nomear, digamos, obter iniciais de nome. Ele receberá nome de usuário como um argumento, e nossa lógica será a próxima. Primeiro, vamos dividi-lo em vários prêmios, e então vamos verificar se temos duas ou mais palavras em nosso apelido, então vamos receber as primeiras letras primeiro para as enfermarias. Então vamos primeiro pegar a área real. Vamos dar um nome, digamos, nome dividido. Então vamos fazer o nome Dot para a ópera. O caso será convertido em maiúsculas com antecedência, e então vamos dividi-lo por espaços vazios. Assim, desta forma, vamos acabar com uma matriz fora de palavras. E então vamos verificar se o comprimento do doc da matriz de nome dividido é maior que um. Então, se tivermos dois prêmios, pelo menos devolveremos o nome Split, Primeira palavra. E a partir da primeira palavra, precisamos pegar a primeira letra. Então vamos abrir os segundos colchetes, e vamos colocar o primeiro elemento. Então vamos colocar um sinal de adição para vir cortar em um distrito. Então vamos colocar contra o nome Bleidt desta vez referência Hubble. O segundo elemento. A segunda palavra. Então vamos colocar uma e outra vez, vamos fazer referência à primeira letra. Colocamos zero. Certo, no caso de termos apenas uma palavra por padrão, vamos retornar. Basta dividir o nome zero, que é Primeira Palavra. E, em seguida, primeiro elemento primeira letra. Tudo bem. E vamos também explorar esta função a partir daqui. Agora, dentro do nosso avatar de perfil aqui dentro de colchetes, nós podemos realmente chamar, obter o nome e ele mostra, e podemos passar o nome que recebemos de adereços. Tudo bem, agora, vamos para Avatar. Aplaudir Bt e componente. E aqui, vamos usar este componente. Então vamos colocar o perfil do carro de Allah como fonte. Vamos especificar o avatar do ponto do perfil e, em seguida, para o nome. Vamos especificar o nome do ponto do perfil. Assim, desta forma, quando temos um arquivo de origem, então o arquivo de origem será exibido. Se não o tivermos, nossas iniciais estarão lá. Tudo bem, vamos guardá-lo e vamos dar uma olhada. O que é que nós temos? Vamos voltar para o painel e agora posso ver que não tenho nenhuma imagem de avatar . Tudo bem, talvez um Vamos enviar um. Vamos abri-lo. Vamos enviar o novo Avatar Avatar foi carregado, e ainda assim eu posso ver quaisquer dados. Tudo bem, então isso é porque na verdade, nós não modificamos nossos contatos. Nossos contatos de perfil. Vamos para o contexto de perfil e dados que passamos aqui não tem nenhum Ah, o que são além de Al Atar Applaud BT na fonte dos EUA. Eu especifiquei o perfil Avatar. Este perfil vem do contexto de perfil de uso. Então, o que precisamos fazer agora que nós re dados do banco de dados? Podemos destruí-la daqui do nosso instantâneo, certo? Tão simples quanto isso. Então também passaremos para nossos contatos. Tudo bem, vamos salvá-lo. E agora vamos dar uma olhada. Se eu for ao meu painel agora eu tenho essa imagem. Mas antes de tudo, parece muito estranho, então vamos modificá-lo um pouco. Vamos ao perfil Avatar e, por padrão, logo antes de espalharmos todos os adereços. Vamos colocar círculo para que ele seja circulado por padrão. Vamos verificar isso. Agora está circulado, mas o tamanho é muito, muito pequeno. Então o que, nós podemos dificar dentro do botão de upload do avatar? Podemos aplicar nomes de classe e isso irá corrigi-lo. Sabemos que a nossa imagem, nossa conversa que especificamos para o nosso editor de tar é 200 por 200. Então vamos aplicar com 200 altura 200 pixels, aquelas classes que você confinou dentro de classes de utilidade. Então vamos salvá-lo. E se formos para o painel agora, temos o tamanho correto para conta-gotas M A. Mas a imagem em si é realmente pequena, então precisamos recitar a imagem real. Por isto. Eu criei este nome mais que você também pode encontrar dentro utilitários, que é imagem de tamanho completo, e ele vai dar com uma altura 100% para a imagem. Então agora parece bom. No entanto, há um pequeno problema. Se atrasei esta imagem, vamos entregá-la daqui agora. Como podem ver, se não tivermos nenhuma imagem, recebo as iniciais de nome, mas também são muito pequenas, então precisamos ajustar o tamanho do telefone. Então, para isso, vamos colocar o tamanho enorme da frente e tudo ficará bem. Vamos verificar isso. Agora. Também tenho o tamanho correto para o meu texto. Então agora talvez vamos mudar o apelido e colocar duas palavras. Vamos colocar e ser. E vamos verificar se temos duas letras como nossas iniciais e em Será que nós temos um exibido aqui ? Legal. Vamos tentar aplaudir o carro de New Allah. Vamos selecioná-lo. E Avatar foi carregado, parece agradável e funciona perfeitamente. Ok, bom. Acho que é a boa altura para terminar este vídeo. Então vamos confirmar nossas mudanças com mensagem. Algo como exibido tem um avatar usuário tar. Está bem, Perfeito. Vejo-te no próximo. 114. Adicione o botão de quarto crio e funcionala: Ei, bem-vindo neste vídeo. Nós vamos adicionar um novo painel de billow inferior que vai adorar a criação de uma nova sala de bate-papo . Vamos lá. Vamos navegar de volta para o código e outros componentes. Nós vamos criar um novo arquivo que vamos nomear Criar quarto bt n motile Não. Sim, vamos completar este componente por enquanto. Deixe ser apenas um olá e vamos realmente usá-lo dentro. Dentro da nossa barra lateral, vamos abrir a barra lateral. E aqui abaixo painel Tuggle, vamos colocar criar quarto Bt e Moto. Tudo bem, agora não vamos nos envolver com o oponente do disco. E aqui vamos definir um botão que vai abrir uma janela modelo com formulário dentro que vamos preencher para realmente criar uma sala de bate-papo. Então vai ficar tudo bem, talvez um componente diff. Então, dentro vamos colocar o botão que será o nosso puxão para abrir a janela da garrafa. Então vamos colocar eu posso à vista. Então isso eu posso ter ícone desligado pode ser criativo, e o texto vai estar criando uma nova sala de bate-papo. Tudo bem, então este botão vai ser um bloco elementos terá cor verde e no clique vamos , Teoh, abra nossa moto. Então vamos realmente usar nosso gancho personalizado para gerenciar o estado mortal. Então este gancho é usado estado modelo a partir daqui começou, infra-estrutura é aberta, aberta e, em seguida, fechar. E para clicar no botão, vamos abrir. Muito bem, agora, vamos definir a nossa janela móvel. Então vamos colocar o elemento modelo do nosso terno. Teremos, como sempre, Heather mortal. Então teremos corpo e vacilar. Tudo bem, bom. Então, dentro da Heather, vamos colocar o título mais. Eles vão pontuar o título e dentro. Vamos colocar algo como uma nova sala de bate-papo e vamos remover este ídolo daqui. Tudo bem, dentro do corpo, vamos definir o formulário e dentro do pé, ou vamos colocar o botão para enviar o formulário. Então vamos primeiro criar o botão. Então ele vai ser um elemento de botão. Vai ser bloqueado. Componente e aparência serão primários. Ok, eu acho. Aparência definida como primária por padrão. Mas vamos manter como está. Tudo bem? Criar uma nova sala de bate-papo. Agora vamos salvá-lo e vamos ver, o que temos? Então agora temos isso criar uma nova sala de bate-papo, já. Nós não temos a margem, então vamos. Então, para este rígido, vamos colocar o nome da classe e vamos adicionar margem superior dois. Tudo bem. Parece bom agora dentro deste corpo iria definir a nossa forma. Então vamos pobre elemento de forma do nosso terno. E dentro deste nascido, vamos definir nossos elementos de entrada, e eles são agrupados sob componentes de grupo formados. Então vamos grupo de forma pobre e dentro desta forma. Mas aberto terá o primeiro rótulo de controle. E então vamos colocar o controle de formulário, que vai ser a importação real em si. Vamos atuar assim. Então, dentro rótulo de controle, nós estamos indo para porta nome da sala em primeiro lugar e controle de formulário vai ser nome, nome e espaço reservado vai ser um espaço reservado vai ser algo como entrar nome da sala de bate-papo e três patos, e ele vai ser um componente auto perto porque é uma entrada. Tudo bem, então se eu passar o mouse neste grupo de formulários, ele diz que não define, então vamos importá-lo do nosso terno. Tudo bem, então vamos definir nossa segunda entrada. Digamos que realmente e ver, o que temos. Então, se vamos clicar em criar nova sala de bate-papo, nada vai acontecer porque não especificamos show prop for motile window. Então vamos colocar é aberto e em altura, vamos colocar manipulador de roupas. Tudo bem, parece bom. Agora vamos verificar e eu vejo que nós adicionamos muito fora do espaço aqui. Então vamos pobre margem superior um tudo agora é. Certo, vamos abrir. E aqui podemos ver que temos nossa entrada, mas está um pouco fora, não cheio com. Então vamos corrigi-lo rapidamente. E quatro dias formam elementos. Vamos fazê-lo para que ele vai fazê-lo tirar tudo com fora do elemento wrapper. Tudo bem, parece bom. Agora vamos seguir em frente e vamos criar o segundo Grupo Estrangeiro, que vai ser a descrição do quarto. Então, para este grupo de reforma, também, vamos copiar rótulo de controle no controle de formulário como este Para este rótulo de controle, vamos especificar descrição, e para este controle de formulário, vamos derramar um componente de área de texto. Então vamos propriedade de classe componente pobre. Vai ser uma área de texto que a Rose dela. Por padrão será igual a cinco. O nome vai ser a descrição. E o espaço reservado vai ser Digamos que entre em Roma. Descrição. Tudo bem. Parece bom. Agora, vamos dar uma olhada se eu clicar nele. Tudo bem. Eu tenho uma descrição. Eu tenho um nome verdadeiro. Ok, agora, talvez vamos definir nosso estado para os dados reais. Então aqui o quê? Vamos Ford, vamos definir o seu estado que vamos nomear, formar, formar, valorizar e definir valor estrangeiro como a função de atualização. Então seu estado vai ser o próximo ele vai ser um objeto, e eu o que eu sugiro que eu sugeri para colocá-lo fora do componente porque nós vamos recitá-lo para o valor inicial quando vamos enviá-lo. Mas vamos enviar o formulário. Então vamos colocar o formulário do show. E vai ser um objeto com conhecimento de nome e descrição. Tudo bem. O mesmo que temos nome prop para a nossa entrada. Tudo bem, então você ficou por aqui. O padrão será a forma inicial. Tudo bem? Além disso, as pessoas precisam do estado de carregamento. Vamos defini-lo com antecedência. Vamos usá-lo quando vamos enviar o formulário. Então o seu estado vai ser falso. Tudo bem, agora, primeiro precisamos lidar quando tivermos que pegar os dados. Então, quando usamos o próprio evento de mudança Então vamos quatro const na mudança de formulário e a coisa com nosso terno, quando usamos no evento de mudança, ele automaticamente nos dá o valor como seu primeiro argumento, não o objeto de evento. Então teremos valor aqui. Então vamos derramar valor de forma CET como valor. E, na verdade, é um pouco diferente com nossas formas de terno. Quando temos um componente de formulário em nossa certeza, ele automaticamente não dá o valor da entrada real que você adicioná-lo. Mas dá-lhe o valor de todo o formulário, por isso é realmente conveniente usá-lo com o estado de uso. Tudo bem, então sobre isso na mudança de formulário, nós estamos indo para portar para o nosso componente de formulário. Então, no manipulador de mudança vai estar na mudança de formulário. Agora. Nós também precisamos de alguma forma validar nossos dados e primeiro, vamos associar o estado real com o formulário. Portanto, ele tem essa propriedade chamada valor de forma. Portanto, deve ser um objeto que interage com o com a forma apenas o nosso estado. Tudo bem, então nós vamos ter um valor de forma ruim. E isso no evento de mudança nos dará o novo valor de formulário quando atualizarmos qualquer elemento fora deste formulário. Então, qual será o nosso objeto no final? Tudo bem. Então, como eu disse antes, agora precisamos de alguma forma validar os dados, o formulário quando enviamos. Bem, nosso terno nos fornece se com métodos auxiliares para conseguir isso, podemos definir um esquema que podemos submeter ao nosso queimado, e então nosso terno irá verificar contra este esquema. Então vamos definir o nosso esquema. Eu aqui no topo para a nossa forma, Vamos defini-lo modelo. E aqui vamos usar o esquema que importamos do nosso terno do que vamos colocar modelo. E dentro deste modelo, precisamos colocar um objeto que representará nosso estado. Então teremos nome. Deve ter a mesma forma que o nosso estado. Então nome vai ser tipo string, que vem realmente de tipos de esquema. Então vamos fazer estrutura-lo string ou talvez tipos de ponto de esquema a partir deste objeto, vamos para d tipo de cadeia de estrutura. Em seguida, vamos usar o tipo de string para definir que o nome vai ser um encolhimento. Então tipo de string, então vamos colocar é necessário para executar a validação e outra mensagem vai ser filmada. Nome é necessário tudo certo, eo mesmo vai fazer. Quatro descrições. Vamos copiá-lo. Vamos renomear para descrição e digamos que a descrição é necessária o legal Pense sobre esta validação esquema moral que ele será validado em tempo real. Agora precisamos enviar este esquema para o nosso formulário. Então vamos encontrar este componente de formulário. E aqui como motile, vamos especificar nosso esquema Moto, nosso objeto modelo aqui. Tudo bem, agora precisamos realmente criar a função de envio. Então, primeiro de tudo, vamos na verdade mudar de formulário. Não é otimizado aqui porque temos um monte fora estados que mudam constantemente, por exemplo, é de valor aberto e estrangeiro. Então, cada vez que teremos em mudança de formulário sendo criado e você copiar esta função. Então vamos memorizá-lo com antecedência para torná-lo mais otimizado. Tudo bem, e agora vamos realmente criar nossa função no envio. Então vamos chamá-lo, digamos, no envio e vai ser uma função de pia com antecedência e aqui o primeiro passo será realmente validar dados. Então, como podemos fazer isso? Como ele pode validar nossos dados em relação ao esquema que definimos aqui. Precisamos realmente usar uma referência para fazer referência ao nosso componente formulário e, em seguida, usando esta referência, podemos chamar seus métodos internos para validá-lo. Então, o que podemos fazer agora? Sabemos que podemos usar ref de reagir. Então vamos colocá-lo aqui. Vamos nomeá-lo forma, ref, e então vamos chamar use ref de reagir. Então vamos passar este formulário ref para este componente formulário. Tão áspero vai ser forma, respiração e ouvir. O primeiro passo vai ser se formulário ref ponto atual verificação de ponto. Então este método de verificação está disponível neste componente de formulário que acessamos diretamente aqui , Então esta verificação irá validar esses dados irá validar o nosso valor de formulário, que é o nosso estado contra o esquema que definimos aqui. Então, se tudo estiver bem, ele retornará ao verdadeiro valor de Bullen. Se não for, será falso. Então vamos verificar se a nossa verificação de valor de formulário não passou. Então, se temos um valor falso, então vamos simplesmente retornar desta função como conselho. Vamos atualizar nosso banco de dados com o novo quarto. Então vamos derramar CET está carregando para true antes de qualquer tarefa assíncrona. E aqui vamos criar um novo objeto que vamos salvar no banco de dados. Então, digamos novos dados da sala. Na verdade, vai ser, ah, ah, onde o nosso estado forma valor. Mas também vamos upend outra propriedade que vai ser criada em então aqui vamos espalhar todo o valor de forma que temos , e então nós vamos colocar criado em e, em seguida, nós vamos importar base de fogo da base de fogo para cima e, em seguida, aqui criou em nós estamos indo para derramar firebase dot banco de dados dot valor do servidor data e hora. Então agora temos os complexos dados de neurônios que precisamos salvar no banco de dados. Então vamos colocar try catch blawg antes de qualquer tarefa assíncrona. E no caso de sair melhor, vamos servir. CET está carregando para falso, e nós vamos matar alerta ponto melhor mensagem de erro com quatro segundos. Tudo bem. Parece bom. Agora vamos chamar o banco de dados Aguarde para o Projeto do Firebase. Então vamos colocar o Dr. Ralf para este árbitro. Nós vamos especificar apenas quartos para que nós vamos manter nossos quartos sob quartos, caminho dentro do banco de dados e empurrar. E você, digamos valor dois banco de dados para que a chave seja gerada automaticamente. Vamos chamar o método push, então e dentro das escolas íamos passar novos dados da sala. Então, depois de termos dados dentro do nosso banco de dados, vamos definir está carregando duas quedas e vamos redefinir nosso estado inicial. Então vamos chamar o valor do formulário de satélite. Vai ser a forma inicial, e depois disso temos de garantir que também fechamos a janela do motel. Então, vamos também chamar roupas. E então vamos colocar outro alerta com informações e vamos dizer valor estrangeiro. Deixe-me abrir citações aqui. Vamos dizer nome de ponto de valor estrangeiro ou, na verdade, deixe-me chamá-lo antes disso assim. Então o valor da forma vai ser vamos dizer que foi criado. E então, novamente, quatro segundos como sempre. Tudo bem, então parece bom. Agora nós realmente precisamos usar está carregando e no formulário enviar. Vamos colocá-lo para este botão que vamos colocar no clique aqui e vamos passar submeter assim. E agora para usar isso é o estado de carregamento. Vamos usá-lo para este botão. Vamos torná-lo desativado quando temos está carregando definido como true. Tudo bem, foi muito. Agora vamos realmente testá-lo. Agora deixa-me refrescar-me só para ter a certeza. Deixe-me entrar. Olá, então vou colocar outra coisa. E aqui, se eu deixá-lo vazio, você pode ver que a descrição é necessária. O formulário está realmente sendo validado em tempo real. Isso é porque definimos o esquema. Tudo bem, vamos pobre Olá. E vamos adiar a descrição desta sala. Vamos clicar em Criar nova sala de bate-papo e podemos ver que alerta não é uma função. Tudo bem, talvez vamos movê-lo como este Alerta. Tudo bem. Erro de ponto de alerta era o problema real. Eu chamei apenas e r R, mas é erro. Então essa é a minha aposta. Tudo bem, agora, vamos tentar mais uma vez. Criar uma nova sala de bate-papo. Vamos colocar “Olá descrição”. Ei, três novas permissões para bate-papo hoje à noite. Tudo bem, porque também precisamos definir regras de segurança para nosso banco de dados. Então vamos abrir regras e aqui vamos definir nosso próximo esquema. Então, próximos dois perfis, vamos copiar isso. Vamos portar também quartos e para salas que vamos especificar. Então, para ler e escrever para tudo dentro daqui, vamos permitir isso somente quando o usuário é autenticado. Então, ao invés disso usando essa verificação, vamos dizer que a permissão de leitura e gravação só é permitida quando desativada, não é igual agora e o mesmo que faremos para basicamente tudo aqui, vamos colocá-la aqui em vez de ideia futura, vamos ter, digamos, quarto I d. E, em seguida, também para leitura. Vamos pacificar o autor, não igual neve e fora, não igual agora. Tudo bem. Parece bom. Vamos copiá-lo. E vamos também sincronizá-lo com nosso arquivo local, que é regras de banco de dados. O Jason. Vamos salvá-lo. E vamos dar uma olhada. Então agora nossas regras são publicadas. Se eu clicar em criar nova sala de bate-papo agora, hello foi criado. E se você olhar dentro do banco de dados agora em salas, nós temos uma nova chave que foi automaticamente gerada pelo banco de dados. E então temos nossos dados criados na descrição e nome. Tudo bem. Parece perfeito. Acho que é a boa altura para terminar este vídeo. Deixe-me cometer tudo. E, em seguida, vamos especificar botão criar para criar nova sala de bate-papo. Ou talvez no novo botão na parte inferior para criar uma nova sala de bate-papo. Muito bem, vemo-nos na próxima. 115. Criando listas de salas de Chat - Parte 1: Ei, neste vídeo, vamos começar a criar Chatham List Inside barra lateral aqui na parte inferior. Vamos lá. Vamos esperar dentro de Bardo GS em primeiro lugar. E aqui, logo após uma criatura em Bt e Moto, vamos colocar o componente divisor do nosso traje e dentro bolha passado. Juntar texto de conversa. E também, vamos mover esta importação para o topo para evitar um excelente aviso. Vamos verificar isso. Parece bom. Agora precisamos realmente definir componentes. Então, na pasta Componentes, vamos criar uma nova pasta que as pessoas nomeiam salas aqui. Vamos colocar dois arquivos novos lista de sala de bate-papo ponto GS e item de quarto. Não Sim, então o item do quarto vai estar vazio agora. E, na verdade, o mesmo se aplica para a lista de chat dentro do lado Bardo Gs Aqui na parte inferior. Em vez desse texto que usamos como espaço reservado, vamos usar a lista de salas de bate-papo. Tudo bem, vamos salvá-lo. Vamos dar uma olhada. Podemos realmente ver o texto Olá para que funcionou. Perfeito. Agora vamos definir o mercado. Vamos esperar que em Chatham Lista e aqui vamos colocar componente suficiente do nosso terno para os adereços passará aparência Satel. Então ele vai ser vertical e invertido. E para o nome da classe, passaremos o próximo. Então precisamos fazer este componente este elemento rastejar um ble. Então vamos passar o transbordamento por quê? Acessar rolagem. Então vamos ver a barra de rolagem sempre. E também vamos passar Alfândega Corvo para torná-lo estilizado. Tudo bem, e então dentro da bolha passado ponto itim suficiente e então item de quarto como esse. Tudo bem, vamos dar uma olhada. Está bem. Parece perfeito. Podemos agarrar o pé-de-cabra, e podemos ver que é um pouco estilizado. Ok, bom. Agora vamos definir nossa marcação para o item de sala. Então vamos dividi-lo em dois. Dave está dentro de cima, parte e baixo, parte dentro. Na parte inferior, vamos definir o nosso texto. Então nós vamos colocar elemento girado, e nós vamos colocar nenhuma mensagem ainda por agora e para o nome da classe. Nós vamos especificar que ele vai ser display flex alinhar itens centro, e vamos aplicar texto preto off 70% capacidade. Está bem. Para a parte de cima, vamos colocar aqui o nome do quarto e há quanto tempo? A última mensagem foi publicada. Então vamos definir classe. Nomeie off display flex e, em seguida, justifique o conteúdo entre dois espaços publicitários entre nossos elementos e alinhe o centro de itens . Certo, então nosso primeiro elemento será três anos com o nome do quarto dentro. Então primeiro vamos definir texto estático, e quando tivermos os valores dinâmicos reais, vamos esfregá-los. Então, para H três, vamos especificar texto desaparecido para evitar estouro. E o segundo elemento é realmente vai ser um novo componente que as pessoas instalam. Então, por enquanto, vamos colocar espaço e vamos dar uma olhada no navegador primeiro. Vamos verificar isso. Como parece, está bem, parece bom. Mas em vez deste x X, vamos usar o tempo atrás React para mostrar que um tempo relativo como este foi publicado há cinco minutos. Duas horas atrás. Um dia vai. Então vamos instalá-lo. Vou abrir cães e copiar este elogio. Depois vou parar o meu aplicativo e instalei este pacote. Vamos esperar e depois continuaremos. Ok, o pacote foi instalado. Vamos começar o up novamente e vamos usar esses pacotes. Então, a partir da documentação, eu vou copiar esta importação. Então eu vou importar para o quarto item e vamos copiar a própria empresa. E vamos colocá-la em vez dessa extensão para que não precisemos localizá-la. Então vamos usar o novo encontro por enquanto. Em vez disso, fora desta data beber apenas para mostrar a hora atual. Tudo bem, então vamos atualizar o aplicativo e vamos dar uma olhada. Ok, então agora nós temos apenas agora perfeito. E eles vão pensar sobre esta biblioteca que irá atualizar este temporizador, digamos em tempo real, mas eu não gosto da aparência deste texto. Então eu vou mudar o nome da turma fora do tempo atrás, componente um pouco. Então, ele vai ser formado normal. E também texto preto. Digamos 45 opacidade. Vamos dar uma olhada agora. Tudo bem. Parece muito melhor. Ok, vamos seguir em frente. E nosso pensamento final aqui será realmente fazer este componente tornar esta lista de sala de bate-papo altura completa. Então, para isso, precisamos calculá-lo porque nosso chat é de página inteira. Então, como podemos fazer isso? Como podemos abordar isso? Sabemos que a nossa página inteira é 100%. Podemos obter a altura fora da parte superior fora da barra lateral, e então podemos subtrair esta parte superior de 100, então vamos ficar a conhecer a altura do resto, que é a nossa lista de salas de chat. Vamos lá. Por isso, não vamos passar o Bardoczky S e a nossa parte principal é este elemento Def. Para obter a altura real disso, def, precisamos usar referências. Então vamos criar uma nova referência, que vamos nomear topo, Bar Arraf e vamos usar usar o gancho ref. Então nós vamos passar este lado de cima desprovido para esta respiração def vai ser topo por árbitro , e nós vamos colocar altura para o estado, então vamos manter o controle disso. Então vamos definir você palco, que vai nomear altura e sentou-se apertado por agora, por padrão, será tal para agora ou 20 que realmente não importa dentro uso efeito. Nós vamos pegar a altura real fora desta definição e então disse para o estado. Então, vamos colocar efeito de uso. E dentro deste efeito de uso, vamos perguntar o próximo. Então, se nós temos top side por ref dot atual porque ele pode ser indefinido em alguns momentos, então vamos verificar se ele realmente definido, então vamos definir altura para cima por Ralf, não altura de rolagem de ponto atual. Então, quando tentamos acessar topo desprovido de corrente, é como se tentássemos acessar elemento quando obtê-lo com documento. Obter elemento por i t. Por isso, é muito útil em alguns casos como este. Nós também queremos executar esta função de retorno de chamada efeito sempre que nosso foram top side. barra F muda. Muito bem, agora vamos passar este estado desta altura para a lista de Chatham para podermos calcular a altura real . Então vamos passar acima altura elemento como altura e dentro lista sala jato vai d estrutura acima altura elemento e, em seguida, o que vamos fazer. Nós vamos aplicar estilo no estilo Lyons, que vai ser altura, incurável, usar CSS calcular função. Então vamos porco alc. Então vamos usar 100% idade menos acima do elemento acima da altura do elemento e no final, vamos colocar pixels porque esta altura acalma em pixels. Agora vamos dar uma olhada. Se o aplicativo for atualizado, nada acontece de fato. Isso é porque nós não cascata eram altura de página inteira. Então, o que está acontecendo que dentro de casa desonesta está aqui? Quem disse h 100 em Lee para o grande componente, mas para fazê-lo trabalhar para um componentes aninhados também. Precisamos definir a altura de 104 crianças para todos os componentes aninhados. Então, para a linha, vamos especificar a idade 100 e para a coluna fará o mesmo Agora. Dentro do fio lateral, já aplicamos H 100 ao seu elemento de educação, por isso funcionará. Agora vamos dar uma olhada e vamos inspecionar o componente. Como você pode ver, já temos altura total e é calculado automaticamente e não teremos nenhum estouro. Ele sempre caberá na altura da página inteira. Então, se inspecionarmos este elemento, podemos ver que a altura é calculada automaticamente para nós. Então temos 138 pixels, que é altura fora da parte superior. Fora da barra lateral. Tudo bem, então parece legal. E eu acho que é isso para este vídeo e o próximo vamos continuar. Então vamos adicionar tudo ao estado do palco e vamos cometer começou a trabalhar com lista de salas de bate-papo . Vejo-te no próximo 116. Criando uma lista de salas de Chat - contexto (parte 2): Ei aí. Neste vídeo, vamos continuar trabalhando em Chatham List. Da última vez definimos Mark. Desta vez vamos criar e gerir o estado. Vamos antes de entrarmos em código. Quero definir como vamos acessar este estado. Então salas de bate-papo. É algo dívida que vamos acessar globalmente dentro da página inicial. Então vamos usar contexto a p I para ser capaz de acessá-lo a partir de dentro componente barra lateral, mas também a partir de dentro janela de bate-papo que ainda não criamos. Vamos navegar para a pasta de contatos e aqui vamos criar o contexto de salas de arquivos. O G s. Aqui vamos criar novo contexto indatável quartos dame contexto com criar função de contexto que vem de reagir. Então precisamos definir um componente, um provedor que irá fornecer a todos os seus filhos com o contexto. Então vamos exportar provedor de salas de const como um argumento. Ele receberá Crianças e ele vai retornar quartos contexto provedor ponto, e vamos colocar Crianças dentro como um valor. Por enquanto, vamos colocar uma corda. E se a temos neste componente, diz, reagir deve estar no alcance. Então vamos importar reagir de reagir. Tudo bem. Bom. Agora vamos definir o estado. Por isso, vai ser simples. É por isso que podemos usar o estado de uso. Então vamos definir salas e salas de satélite por padrão. Ele será definido para montar, e teremos nossos dados dentro do efeito de uso quando o componente monta. Então vamos para o efeito de uso e dentro primeiro, vamos armazenar nossa referência para as formas de dados. Então, se abrirmos o banco de dados, lembramos que armazenamos nossos dados em salas, barra na sala I d. e então vamos dados. Então, o que vamos fazer, vamos colocar um ouvinte em tempo real nas salas para que possamos obter atualizações em tempo real. Vamos criá-lo valioso que vamos nomear lista de quartos áspero e vai ser banco de dados quartos ref ponto. Então agora temos a referência. Então vamos colocar um ouvinte em tempo real usando ponto no método. Então vamos ligar para a lista de salas. Ralf pensou no valor e, em seguida, para o retorno de chamada. Quanto a agora, ele recebe camisa de pressão. Quanto a agora, vamos Cônsul olhar, valor de ponto instantâneo certo. E porque é um ouvinte em tempo real, precisamos cancelar a assinatura dele porque esta é uma assinatura. Então vamos fazer isso dentro da função de limpeza. Efeito fora de uso aqui. Nós vamos colocar a lista de quartos ponto áspero fora ele vai separar todos os ouvintes em tempo real desta referência dentro do banco de dados. Tudo bem, vamos salvá-lo. E vamos realmente usar esse contexto. Vamos navegar até a página inicial. E aqui vamos embrulhar tudo em torno de provedor de quartos. Ok, vamos dizer com e vamos dar uma olhada. Se eu ir para o console, eu posso ver que eu tenho valor instantâneo, que é um objeto onde cada chave é idéia sala e, em seguida, vai dados. Então temos esse capataz porque temos o banco de dados baseado no Jason. Mas estes não são exatamente os quatro meses com que queríamos trabalhar. Precisamos de uma via aérea. Então vamos criar uma função auxiliar que irá transformar este tipo de objeto em uma matriz. Então vamos definir uma nova função dentro de ajudantes togs que vamos nomear. Vamos uma matriz transformar dois com I d. Ele receberá valor instantâneo como um argumento e ele irá retornar. A próxima coisa primeiro é verificar se o valor do instantâneo existe. Se os nossos dados não forem agora, se tivermos algum dado. Então, se esse for o caso, então vamos colocar a lógica. Caso contrário, voltaremos e esvaziaremos. Certo. Então, qual será a nossa estratégia? Vamos chamar objeto de método do beijo para colocar todas as idéias de sala em uma matriz. E então vamos mapear cada valor, cada quarto que eu d para esses dados. Vamos lá. Então vamos colocar chaves de ponto de objeto fora do valor instantâneo para obter todas as crianças como uma matriz. Então vamos mapear cada valor desta área onde cada elemento é a sala que eu d para um objeto que será todos os dados da nossa sala. Nós podemos acessá-lo com valor instantâneo fora da sala I D. E então nós vamos anexar i d outra propriedade, que vai ser quarto I d. Tudo bem, vamos navegar duas salas contexto e aqui em vez disso, off usando o valor de ponto instantâneo, vamos realmente transformá-lo menos grandes dados novos e valiosos aqui. Vamos colocar transformação em matriz com i d. e vamos passar o insight do valor do ponto instantâneo. Tudo bem. E vamos CTA consular mais tarde para ver o que realmente recebemos. Agora, Como eu posso ver, eu tenho uma matriz fora dos quartos e eu tenho dados e também eu tenho I d como uma propriedade. Tudo bem, então é isso que eu quero. Agora, vamos atualizar o estado. Vamos chamar salas e colocar dados dentro. E então vamos passar este estado para o contexto como nosso valor de que são salas. Tudo bem, é isso por enquanto. Eu acho que no próximo vídeo, vamos terminar isso e vamos exibir nossos quartos do banco de dados. Mas, por enquanto, vamos terminar este vídeo confirmando nossas mudanças. Obter commits traço M e para o relatório de mensagem criado salas contexto. Está bem, vejo-te no próximo. 117. Criando uma lista de salas de Chat - exibira como links (parte 3): Ei aí. Neste vídeo, vamos exibir salas de chat que armazenamos dentro do banco de dados, usando a marcação e o contexto que criamos nos vídeos anteriores. Vamos, vamos abrir nosso código. E aqui vamos abrir componente de lista de salas de bate-papo. Aqui as pessoas consomem o nosso contexto. E novamente como antes, em vez de usar o contexto de dicas e, em seguida, especificar o contexto importando o arquivo, vamos criar um gancho auxiliar dentro de salas, contatos. Vamos exportar. O Const. Vai nomeá-lo. Use salas, e vai ser uma função que nos retorna o valor de contatos. Então vamos colocar para usar o contexto e pacificar o contexto dos quartos. Desta forma, vamos evitar chamar dicas contexto com salas, contexto cada vez, mas usar salas. Tudo bem, então dentro de componentes da lista quebrando. Vamos chamar este gancho de salas de uso e agora temos o valor de contexto. Agora a coisa é que essas salas podem ser nulas no momento em que tentamos acessá-lo, porque nosso estado inicial é maçante e somente quando componentes monta obtemos os dados reais. Então precisamos colocar corrida condicional, beber e checar isso aqui dentro. Suficiente. Vamos colocar se não temos quartos. Então vamos mostrar o componente Lauder que vem do nosso terno. Ele será centrado, e será centrado. Vertical E. Além disso, terá conteúdo, o que dirá carregamento e terá baixa velocidade. Tudo bem. E também, vamos especificar tamanho para tamanho médio. Tudo bem, citação. Agora, vamos exibir segunda renderização condicional para realmente mostrar dados vamos mapear cada elemento da matriz, que é salas que transformamos com transformação para chegar com I d a um j seis elemento. Então vamos perguntar se temos quartos e quartos ponto terra é maior que zero Onley. Então vamos ligar para a sala, começar o mapa dentro, vamos ter o pequeno Tim e temos um mapa. Este quarto eu tento a amar componente item como esse. E não se esqueça, quando usamos este mapa de pontos, precisamos especificar a chave prop. Então vamos colocar o quarto escuro. E então vamos passar o objeto da sala como um quarto, propriedade para quarto item como este. E então vamos passar o objeto da sala como um quarto, Tudo bem. Parece bom. Agora vamos abrir o item da sala no próximo aqui, vamos destruir o chur ou a própria propriedade, e dentro do componente, vamos conseguir o nosso equilíbrio novamente, estruturando o objeto da sala desta vez. Então, teremos criado em e também teremos o nome do quarto. Então, em vez deste imposto estático, vamos exibir o nome da sala que nós D estrutura e também quatro vezes atrás componente. Se não tivermos mensagens, mostraremos o tempo quando esta sala tiver sido criada. Então vamos apenas passar Nova data criada em tudo certo, Vamos salvar e vamos dar uma olhada. Perfeito. Agora podemos ver que o quarto foi criado há um dia e o nome do quarto é Olá, Talvez vamos tentar criar mais um quarto. Então, vamos clicar no nosso Moto. Vamos passar se eu sabia o nome Roll e qualquer relatório para descrição. Se você clicar sobre isso, podemos ver que os dados estão sendo atualizados em tempo real, então tudo funciona perfeitamente. No entanto, eu também quero transformar esse componente em um link. Então, quando clicamos nele, nós realmente ir para a página de bate-papo. Tudo bem, então vamos voltar para o código e vamos para a lista de salas de bate-papo aqui para este item de rapé. Primeiro. Acho que eu quero fazer, Eu quero especificar classe componente para que ele irá renderizar este item suficiente usando este elemento fornecido para uma classe competente. Vai ser um componente ligado que vem do roteador do reator burro para este componente de ligação , vamos pacificar sua propriedade, que é também. Então vamos colocar dois. E vamos usar interpolação string para especificar qual caminho haverá se clicarmos nele. Então, vai ser chats barra sala I d. Então vamos abrir cadeia contar população e vamos colocar idéia quarto. Tudo bem, legal. Vamos verificar isso. Agora. Se eu clicar nele, você pode ver que o Ural muda e nós realmente temos a funcionalidade. Mas eu também quero tornar este item ativo sempre que tivermos o caminho correto correspondente ao link. Então o que precisamos fazer como antes com bilheteria, precisamos obter nossa localização atual. Então, vamos usar gancho de localização que vem de reagir Router pacote para baixo. Agora, para este rapé, vamos passar mais uma propriedade, vamos passar mais uma propriedade, que vai ser chave ativa, então chave ativa vai ser localização, não nome do caminho. Então precisamos pacificar ou, digamos, associar cada item de amor à sua corrente. Vamos uma chave. Então, para isso, precisamos passar mais uma propriedade, que vai ser chave de evento. E ele deve corresponder à chave ativa, que é o nome do caminho do ponto do local. Então, será bate-papos de barra, sala de barra I d. Então, para chave de evento, vamos especificar exatamente o mesmo que para a propriedade. E agora vai funcionar. Vamos verificar isso. E agora, quando a nossa localização corresponde, temos a animação legal e temos a chave ativa. Então funciona perfeitamente. Mas eu quero modificar um. Pense em vez de bate-papos, eu quero usar apenas bate-papo como este. Certo, vamos checar mais uma vez. Se eu mudar para a página de bate-papo, eu tenho este elemento ativo. Tudo bem. Bom. Então é isso. Vamos terminar o nosso vídeo. Vamos colocar tudo para o estado do palco, e então vamos chamar, obter commit com as salas de bate-papo exibidas. Tudo bem, legal. Este é o fim para este vídeo. Da próxima vez vamos construir nossa parte direita fora do site e vamos começar a construir janela de bate-papo. Vejo você lá 118. Criando o layout aninhado para a página de página: Ei, Neste vídeo, vamos criar Lee nosso para a página inicial. Então, por enquanto, já construímos a parte esquerda, qual barra lateral? Agora vamos definir o nosso papel certo, e vamos ver como eles vão jogar um “vamos” responsivo. Então vamos abrir o arquivo dos togs domésticos. E aqui teremos um ninho, uma seca. Então, quando clicamos em uma sala de bate-papo, podemos ver que vamos para a sala de bate-papo barra i d. Para isso, precisamos criar um acidly out porque vamos mostrá-lo na página inicial. Então o que eu propus para dio aqui em vez de apenas usar um arquivo diretamente, vamos criar para não a pasta home. E aqui vamos colocar todas as secas do Nestor e a DGS em casa vai estar dentro de togs índice . Então vamos criar nova pasta home dentro vamos colocar casa do que vamos renomeá-lo para indexar pontos gs. E aqui nosso ninho a seca vai ser página de bate-papo. Então vamos criar um novo arquivo que vamos chamar Chat Doggy S. e, por enquanto, ele vai estar vazio. Porto solícito. Alô? Tudo bem, então dentro deste índice Se nós o salvarmos, vamos atualizar Não é possível abrir o diretório. Tudo bem, talvez vamos reiniciar o aplicativo e ele vai funcionar. Deixe-me refrescar. Tudo bem, agora parece bem. Bom. Vamos continuar. Então nosso primeiro passo será definido. Ah, onde? Nestor Seca. Então aqui, ao lado desta coluna, vamos definir instrução switch e aqui vamos derramar a rota de bate-papo e a barra lateral Ele será persistido porque é o nosso layout. Então, dentro disso, que vamos derramar e porque nossa página inicial já é privada, não precisamos derramar secas ninho. Também rotas privadas. Podemos usá-los como públicos porque nossos pais são privados. Isso significa que eles já estão protegidos. Então ele vai ser rota exata eo caminho vai ser barra chad slash chat I d para seguir a grade. Também precisamos colocar uma coluna aqui. Então vamos colocar coluna e dentro vamos derramar chat e vamos também importado desta pasta. Então deixe-me especificar o chat e vamos usar o chat. Tudo bem, agora parece bom. Vamos definir como Maney colunas a página de bate-papo vai levar. Assim, em pequenos dispositivos, levará todas as 24 colunas e em dispositivos médios. Vamos tirar o resto disto, por isso vai ser 16 e, em seguida, o nome da classe também vai ser uma igreja 100. Agora vamos dar uma olhada e vamos ver. Tudo bem, temos Olá, vamos inspecionar e vamos tentar rece gelo. Tudo bem, então vemos que quando estamos em pequenos dispositivos, temos isso, digamos, de cima para baixo, Lee fora. Não é isso que queremos. Queremos esconder esta saudação em pequenos dispositivos e porque precisamos não apenas esconder isso, também queremos ter certeza de que sempre que vamos para a sala de bate-papo, não vemos a barra de navegação. A barra lateral. Então é por isso que precisamos colocar algum tipo de ah, digamos condição complicada. Então, primeiro de tudo, precisamos definir nosso ponto de interrupção quando estamos na área de trabalho, e isso é quando temos 992 pixels. Então, primeiro vamos definir é desktop, e vai ser o resultado do uso gancho de consulta de mídia que definimos anteriormente. E aqui vamos perguntar se homens com IHS 992 pixels, certo? Então, neste caso, teremos desktop. Além disso, precisamos tomar nossa segunda condição quando estamos exatamente na página inicial para que possamos mostrar a barra lateral em pequenos dispositivos, não na página de bate-papo, para que ele fique escondido. Então vamos definir é exatamente assim. Vamos destruí-lo do uso, não do uso. Media Query usado muito rota. É outro gancho que vem de reagir roteador, o mesmo que usar local. Mas este cozinheiro nos dá, digamos, pensamentos relacionados à nossa rota atual e jogo de seca. Então, um desses adereços é exato e ele vai dizer se estamos atualmente nesta rota definida , que é home page. Então, quando vamos estar em apenas barra ele vai nos dar é exatamente igual à verdade. Tudo bem, então agora vamos definir nossa condição. Então vamos pobre pode renderizar barra lateral e vamos perguntar se ele é desktop para se ele é exatamente passado em Lee, então nós seremos capazes de renderizar barra lateral. Então, agora aqui, vamos derramar a próxima lógica. Então, se pudermos renderizar barra lateral, então vamos colocar esta coluna e agora aqui precisamos também definir, digamos, um quatro por quatro horas ou se alguém abrir uma página de bate-papo quebrada, podemos vivê-la vazia e tudo ficará bem. Mas vamos fazer isso chique e vamos parar aqui e aqui. Vamos perguntar se é só para desktop. Então nós queremos mostrar a coluna, e ele terá, eu acho, o mesmo lee aqui fora. Então vamos copiá-lo. E lá dentro, vamos puxá-lo. Digamos que apenas o texto que dirá Por favor selecione o chat e o nome da classe vai ser tributado centro e margem superior direitos Fage. Agora vamos dar uma olhada. Então, sempre que agora estamos em bate-papos barra menos espaço eu d. Podemos ver apenas conversa na página. Se eu remover isso e navegar para a página inicial, eu posso ver apenas barra lateral, por isso parece bom. Se eu redimensioná-lo, eu posso ver os dois para que eu possa ver minha sala de bate-papo, mas em vez disso fora do bate-papo real. Sempre que não estiver selecionado, eu posso ver a seleção da polícia tiro no total de volta para fora, então ele funciona como 404 e se eu selecionar um dos chats, eu posso ver a janela de bate-papo real. Acho que este é o fim para este vídeo. Da próxima vez, continuaremos. Mas, por enquanto, vamos apenas cometer nossas mudanças. Vamos colocar, Obter em tudo. Obter commit e digamos que criado nós nosso para home page e criou página Shat para a direita. Incrível. Vejo-te no próximo. 119. Criando o layout/Component: Ei, neste vídeo, vamos criar Lee para conversar página que podemos ver à direita em vez disso . Alô? Vamos lá. Vamos voltar para decodificar. E aqui na pasta Componentes, vamos cumprimentar e sua pasta e que vamos nomear Shatt Window dentro. Vamos criar mais três pastas e cada uma representará cada parte desta página. Então nós vamos ter primeiro Pasta vai ser mensagens. Então nós vamos derramar cima e baixo assim, dentro de um lugar de bolha, todos os componentes correspondentes. Então, dentro de baixo, vamos colocar togs índice e ele vai ficar vazio por agora do que o mesmo que vamos fazer para o resto. Então aqui nós vamos colocar togs índice, mas um nome que ele mensagens que vamos colocar mensagens dentro, vamos salvá-lo e fechar. E o nosso último componente será esta palestra. Então vamos criar outro índice togs. E vamos colocar o topo com a visão de texto superior. Tudo bem, vamos salvá-lo e vamos navegar para a página de bate-papo. Então aqui, dentro desta definição, vamos derramar outro def. Isso será um rapper para o Chat Top, e vamos importá-lo em um segundo. Então vamos servir outro Dave. E dentro vamos colocar mensagens e o mesmo. Vamos aplicar para o fundo do Chade, todos os direitos e para cada um destes Daves. Se abrirmos filha principal um CSS. Aqui temos o gráfico de classes superior, fundo do Chade e meio tiro. Então vamos usá-los para o nível superior do Porter chat Top quatro mensagens. Vamos colocar um cara no meio e para mas, um, um, vamos colocar o nome da classe Chad Bottom. Muito bem, agora, vamos importar estes componentes. Então, primeiro, vamos importar o chat. Contar a partir de Vamos navegar dois componentes, janela de bate-papo e topo. Então vou copiar três vezes. Então eu vou usar o fundo e as mensagens, e então eu vou substituí-los com o fundo do bate-papo e mensagens. Tudo bem, parece bom. Vamos dar uma olhada. Então, agora, se com um novo que podemos ver, temos mensagens superiores e inferior e vamos remover este embrulho, def. E vamos dar uma olhada mais uma vez. Agora temos mensagens de topo e de baixo na parte inferior. Tudo bem, bom. Agora vamos definir nossa lógica inicial para a página da sala de bate-papo. Então, primeiro de tudo, vamos pegar este Chad I D. De nossos perímetros como você se lembra dentro da home page com pacificado-lo como apenas chat I d. Então vamos agarrar a partir de programas de uso gancho que podemos usar usando pacote de rotor reagir. E então podemos pegar todos os nossos quartos que temos dentro do contexto, como você se lembra. Então vamos usar salas de uso gancho que criamos anteriormente. E agora vamos realmente obter nossos dados atuais da sala. Então, o que precisamos fazer? Primeiro de tudo, precisamos verificar contra esta sala porque pode ser não por padrão, como você se lembra. Então vamos perguntar se os quartos não existem ou se este valor é agora, então nós vamos derramar componente lei ordem que vem do nosso processo. E novamente ele será centrado verticalmente como antes. Ele terá tamanho médio. Ele terá carregamento de conteúdo e a velocidade vai ser lenta. Tudo bem. Nosso próximo passo é conseguir nosso quarto atual deste quarto é uma tarifa. Então vamos porta const sala atual vai ser quartos ponto encontrar vamos ter item quarto. Então nós vamos perguntar de i d é igual a chat. Eu d tudo bem. E no final, se não tivermos espaço atual. Então, se colocarmos um aleatório seu l que não existe dentro da matriz desta sala, então vamos retornar H seis elemento com o nome da classe, centro de texto e margem de página superior. Isso vai dizer, Chad, eu não encontrei. Tudo bem. Parece bom. Vamos remover isso, Lauder. Vamos mover esta importação para o topo. Vamos salvar. Vamos dar uma olhada. Tão carbonizado, este não foi encontrado. Tudo bem, estou correndo aqui. Deixe-me colocar a negação na frente dela. Então agora vai funcionar. Tudo bem, então nós conversamos mensagens no fundo. E se colocarmos um psiquiatra aleatório aqui, mas seremos baleados não encontrados. Está bem, Perfeito. Então é isso para este vídeo no próximo vídeo, eu gostaria de falar sobre problemas de contexto e por que é uma má idéia usar diretamente salas, gancho. Vamos cometer nossas mudanças e terminar essa. Então vamos em tudo o que você começa sistema que vamos cometer nossa mensagem e vamos dizer criado Klay, nossa página de quatro carbonizados. Tudo bem, bom. Vejo-te no próximo. 120. Problema de API de texto e uma solução Potencial: Oi contexto. AP é incrível, não é? Mas sempre com qualquer boa ferramenta, há também um lado negativo. O problema com o contexto é que podemos selecionar uma parte de seu valor. Não podemos definir um seletor por essa razão. Sempre que o contexto é consumido com o gancho de contatos de uso, mesmo que o valor não seja usado e ele muda, o componente será renderizado. Imagine o contexto que passa para baixo e objeto com a próxima estrutura. Em um componente em que Título é exibido, gostaríamos de obter apenas imposto sobre o título, certo para que possamos destruir o texto do título do valor do contexto e parece que tudo bem. No entanto, para o contexto, não importa se ele é destruidor ou você tentando selecionar parcialmente elementos. Ele sempre lhe dá todo o valor de contexto a partir de agora, uma vez que o componente título recebe o valor sempre que qualquer coisa dentro do nosso objeto muda. Por exemplo, pesquisando colocar, o componente título será renderizar, e isso é ruim. Para resolver isso, podemos realmente dividir o contexto em dois provedores de contexto separados, um por chave de objeto. Dessa forma, dividimos responsabilidades e renderização não será acionado porque vamos consumir apenas o que precisamos dentro de um componente provedor não foram limitados a você. Apenas um contexto pode combinar vários contextos em um provedor. É muito útil quando passamos pelos contatos, por exemplo, exemplo, o resultado do estado de uso, estado e sua função de atualização para eles. Serão dois contextos separados agrupados em um provedor. Então, agora, se dentro de um componente consumimos contexto que fornece o componente de função de atualização não será renderizado. Quando esse estado muda, ele só será renderizado se o valor real fora do contexto consumido for alterado, que é a função de atualização. Neste caso, isso funcionará para a maioria dos casos. No entanto, há situações em que gostaríamos de passar um objeto grande através do contexto, e criar um novo contexto para cada chave será um exagero. Para estas situações. Há um seletor de contexto de uso do pacote que nos fornece funcionalidade para selecionar parcialmente o valor do contexto. Ele vem com as poucas limitações, mas quando usado sabiamente, renderizações podem ser evitadas em tudo. Só para salientar, tudo isso é atencioso ao usar patos credo em vez de contexto um P I. Para a gestão do estado, no entanto, Redox tem uma curva de aprendizagem e traz mais complexidade, dependendo da aplicativo. Você provavelmente não precisa disso. É por isso que usamos o contexto. A p i no próximo vídeo que vamos instalar usar seletor de contexto e vamos ver como ele pode nos ajudar a ver que 121. Problema de API na prática - criando o contexto da sala atual: hi nesta mídia irá criar contexto para sala de bate-papo aberto atualmente usando cues Context Lecter pacote. Antes de começarmos, vamos explorar como tudo vai ser tratado. momento, há salas de contexto que rouba toda a página inicial. Dados de contexto são lista de salas de bate-papo com assinatura em tempo real. Isso significa que se alguma coisa mudar em qualquer contexto fora da sala, o valor será atualizado dentro de salas sombra GS. O contexto está sendo consumido. Então qualquer atualização em qualquer sala causará uma rendição. Duas páginas de chat atualmente abertas, mesmo que a data AB não tenha sido relacionada a ela. Portanto, dentro de Chad Ogea s, vamos fornecer um novo contexto que vamos nomear contexto de sala atual e vamos passar atualmente abre dados de sala para esses contextos. Vamos usar o seletor de contexto. Imagine uma situação quando o nome da sala atualmente aberto é atualizado. Ele criará uma rendição para sala atualmente aberta e valores que passaremos para o contexto atual da sala também serão evitados. Há um componente que consome o contexto atual da sala e ele exibe apenas a descrição, não o nome, porque fora o seletor de contexto de uso, esse componente não será renderizado. As alterações afetarão em Lee o componente que exibe o nome. Certo, vamos colocar tudo em prática. Eu já abri oficial obter página web feliz para uso pacote seletor de contexto E se eu rolar para baixo a partir da parte de instalação, eu posso ver que eu preciso copiar este comando. Então vamos fazer isso. Vamos navegar de volta ao código e dentro do Terminal Integrado eu vou executá-lo e vamos esperar até que ele seja instalado. Aperfeiçoe os pacotes lá. Agora vamos executar o aplicativo e não vamos voltar para a documentação. Assim, a partir da parte de uso, podemos ver que na verdade não é diferente de como usamos o contexto de criação normal. Então, vamos navegar de volta ao código. E aqui em seu contexto, pasta menos grande arquivo novo que vamos nomear contexto sala atual. Desonesto. Sim, aqui. Vamos criar contexto de sala atual e vamos usar criar contexto, aquele que vem de não reagir. Vamos converter Teoh uma jóia de seis meses e do seletor de contexto de uso. Tudo bem, então a próxima parte será criar o componente provedor. Então vamos colocar exportação const provedor de sala atual para que ele vai receber Crianças e, em seguida, também ele vai receber dados para que ele vai levar alguns dados que vamos passar para este provedor. Então aqui vamos retornar atual do provedor Context Dar. E nós vamos crianças pobres lá e por valor. Vamos pausar os dados, então o componente do provedor vai ser como um intermediário. Tudo bem, então se temos nossa reação, devemos começar o escopo. Então vamos importar reagir de reagir ou eu vou. Agora vamos realmente ver como podemos selecionar alguns dados daqui? Então precisamos usar contexto de uso, seletor. Então precisamos fornecer contexto que queremos consumir. E então nós fornecemos o Colback que irá aumentar nosso valor onde o argumento é nosso estado atual . Então vamos navegar um pouco para baixo daqui. Podemos ver que podemos realmente usá-lo assim. Então vamos copiar isso e vamos colocá-lo aqui no contexto atual da sala. Então o que vamos fazer, vamos transformá-lo em nosso próprio gancho personalizado. Vamos importar usar o seletor de contexto do próprio pacote, e então vamos transformá-lo em um gancho. Então vamos convertê-lo para funcionar. E em vez do primeiro nome, vamos usar o quarto atual e também vamos exportá-lo. E para este uso sala atual, vamos apenas passar seletor. Então vamos passar seletor aqui. E em vez de contexto pessoal, vamos derramar contexto de sala atual e para seletor, vamos fornecer seletor. Já estamos aqui. Agora, não vamos voltar para nossa página de bate-papo. E aqui, em vez desses colchetes vazios em vez de fragmento reagir, vamos usar esse provedor. Então vamos colocar o provedor de sala atual, e precisamos passar os dados que colocaremos neste contexto. Então vamos colocar dados E para dados, vamos criar um objeto que vamos nomear, digamos dados atuais da sala. Então aqui vamos criar este objeto, e aqui vamos passar os próximos valores. Então, da nossa sala atual, vamos atingir o nome e a descrição destruindo os valores. E então vamos passar nome e descrição para corrente a partir de dados que passarão para o contexto D. Tudo bem, então se salvarmos e salvarmos tudo aqui agora, se voltarmos ao nosso aplicativo, nada realmente será mudado. No entanto, se vamos dizer que vamos para o chat top aqui, vamos usar o gancho de sala atual que criamos. Então vamos talvez selecionar um nome e para seletor vamos passar Estado e do estado, vamos escolher o nome ou talvez não, estado. Vamos colocar inveja por valor assim. E agora, em vez de cima, vamos exibir esse nome do contexto. Tudo bem, então se eu disser isso, se eu atualizar, eu posso ver Olá o nome do quarto que passamos para os contatos e se eu mudar, ele será mudado. Então é isso. É assim que podemos realmente atingir valores de pico a partir do contexto. E também é muito importante notar que esses valores que escolhemos do estado que escolhemos do contexto é importante entender que podemos selecionar objetos porque objetos são comparados por referências. E se abrirmos a documentação para este pacote, se rolarmos para baixo até limitações, podemos ver que o gatilho de provedor renderiza Onley se o valor de contexto for preferencialmente alterado, então os objetos são preferencialmente mudou. Por isso, temos de ter cuidado com isso. Precisamos selecionar apenas tipos primitivos que o objeto não é. E também, se olharmos para dentro das limitações, precisamos envolver nosso componente em torno de reagir, mamãe. Então vamos também importar mamíferos de reagir e vamos envolvê-lo em torno dele assim. Então agora o nosso valor está memorizado. E se algo mudar para esta corrente a partir de dados, vamos uma descrição. E dentro deste componente superior, só consumimos nome. Este componente não será atualizado quando a descrição for alterada. Então é isso. Uma coisa a apontar aqui é que, como mencionei anteriormente, se consumirmos ambientes dentro deste componente, e se algo mudar, todo o componente será renderizado. Então, incluindo este chat top mensagens e chat bottom. Mas porque usamos mamíferos aqui, Teoh, memorizamos nossos componentes. Reduzimos significativamente a árvore de atualização para que somente essas quedas de embalagem sejam atualizadas em cada alteração. Componentes subjacentes mensagens de bate-papo up na parte inferior do bate-papo não serão renderizadas. Então é isso. Esta é a caverna. Está fora do contexto. AP I Vamos terminar este vídeo. Então vamos confirmar tudo e vamos colocar a próxima mensagem criada contexto de sala atual com seletor de contexto de uso. Muito bem, vejo-te no próximo 122. Criando o Chat inicial: Olá. Neste vídeo vamos começar uma página de chattel de construção. Vamos, Vamos navegar de volta para o código e vamos abrir togs índice que representa na parte superior aqui. Em vez deste nome, vamos derramar outro def. Isso será outra parte superior. Então, para este difícil nome de classe sair no display flex, justificar o conteúdo entre o centro de itens de linha dentro vamos puxar a idade quatro aderência e dentro exibição rebelde Ah, foram nome do chat. Então aqui de um nome vocal e nome de classe para este pan será texto desaparecer e também vamos colocar e eu posso aqui na frente deste texto quando estamos em dispositivos móveis para que não possamos voltar para a página inicial. Então aqui, vamos embarcar e eu posso e classe competente vai ser um link que vem de reagir Router burro do que o próprio Eiken vai ser círculo de seta. O tamanho esquerdo vai ser duplo X E porque é um componente de link, também precisamos fornecer a propriedade que levará à página inicial, certo? E também vamos derramar o nome de classe condicional para este Aiken. Então vamos perguntar se estamos em dispositivos móveis. Então vamos colocar nomes de uma classe. E se estivermos na área de trabalho, vamos colocar outros nomes para isso. Vamos usar o gancho de consulta de mídia que usamos mais cedo, e vamos criar o Bullen, que é móvel. E, em seguida, vamos usar Media Query a partir de ganchos personalizados e dentro de uma porta de bolhas marcas com off 992 pixels. Tudo bem, então quando estamos em dispositivos móveis, vamos puxar o display no bloco de linha do que rebater vai ser margem zero direita para texto azul e Lincoln estilizado para fazer nosso elemento link totalmente em estilo. E se estamos em dispositivos desktop, então nós simplesmente não exibimos este Aiken. Então vamos economizar e inspecionar. O que temos nós? Agora temos o nome do quarto. Se eu inspecionar e redimensionar a janela, posso ver este botão aqui. Quando eu clico nele, eu volto para a página inicial para ver Chatham. Tudo bem, parece bom. Vamos continuar. Então aqui, ao lado deste h quatro, vamos colocar barra de ferramentas de botão que vem do nosso terno, e isso ia ser nosso para fazer Então também, vamos colocar o nome da classe fora Ws No rap. Tudo bem, unificado um novo. Tudo bem, então isso é para fazer no próximo dia se vamos colocar outra definição e vai ser a nossa parte inferior. Então, para esta parte inferior, vamos colocar, exibir, exibir, flexionar, justificar o conteúdo entre e alinhar itens no centro. Vamos derramar como elemento divertido que também será nosso para fazer. E também, vamos colocar um botão aqui, então quando clicarmos nele, uma janela modelo se abre e podemos ver a descrição do quarto. Então vai ser outro componente que vamos criar e vamos chamá-lo Noivo Info, BT e Moto Dar g s tudo bem. Por enquanto, vai ficar vazio. Vamos usá-lo lá dentro. Índice de togs aqui. Nós vamos derramar de informações BT e Moto, certo? Digamos com e agora vamos definir nosso componente. Primeiro de tudo, aqui vamos mostrar a descrição do quarto e o nome do quarto também. Então, para isso vamos usar o contexto, Eleitor. Então, primeiro de tudo, vamos má descrição aqui, e ele vai ser usado carro e gancho jogado. Então obtemos o nosso valor e do valor crescemos descrição. E você se lembra que eu lhe disse que é importante não selecionar objetos porque eles são comparados referencial e Então isso significa que se precisamos selecionar vários valores de um objeto , precisamos selecioná-los separadamente. Então eles se tornam um valor primitivo porque a descrição é uma string. Por isso, é um tipo primitivo. Então, também precisamos exibir o nome. Então vamos fazer exatamente a mesma coisa. Use a sala atual, e nós vamos ter o nome do ponto da sala. Muito bem, agora, dentro da nossa marcação, vamos despejar um elemento de botão do nosso fato dentro. Nós vamos derramar informações de quarto e aparência vai ser piscar e classe Nome vai estar batendo em X acesso é zero agora, porque nós temos um motile que vamos usar novamente nosso próprio gancho personalizado, que é usado estado mortal. Então deixe-me importá-lo. E a partir deste gancho que vamos agarrar está aberto, fechado e aberto. Agora, ao lado deste botão elementos que podemos pagar um componente moral do que para o show propriedade que vamos definir está aberto para na altura. Vamos colocar roupas. E dentro deste mortal, como sempre, teremos o ponto mortal Heather. Então teremos corpo e rodapé. Então vamos substituir esses valores , Peito dela. Ok, então para a modelo Heather, nós vamos colocar o título do ponto modelo e para o título, nós vamos derramar sobre o nome do quarto do que para rodapé. Vamos colocar outro botão que vai fechar a moto. Então vamos colocar roupas, então vamos especificar em Click vai ser roupas e também vai ser um elemento de bloco, certo? E nós somos corpo, o que vai especificar algo simples, que vai ser um seis tack. E vamos colocar a descrição e o nome da classe vai ser margem inferior em seguida, irá a descrição em si. Então vamos colocar a descrição. E agora vamos salvar e remover essa def e substituí-la pelo contexto de reação . Vamos também mover a importação para o topo. E também não usamos esse manipulador aberto. Vamos colocá-lo por dias. Botão no clique vai estar aberto. Tudo bem, vamos guardá-lo e vamos dar uma olhada. Agora temos o botão de informações da sala que se parece com um link. E quando clicamos nele, temos uma janela moral que diz sobre Hello. Descrição Descrição. Ei, perto. Vamos testá-lo em seu próprio nome novamente. Temos uma descrição estranha e tudo funciona bem. Então, este é o fim para este vídeo. Vamos cometer nossas mudanças. Deixar que as pessoas cheguem a tudo e depois se comprometam. Digamos que, começou a construir Chat Top Criou uma descrição da sala. Modoff. Tudo bem, Perfeito. Vejo-te no próximo. 123. Denominação de dados - criando o fundo de Chat: Olá. Neste vídeo, vamos começar a criar fundo carbonizado. Vamos antes de começarmos. Quero mencionar que no vídeo anterior, quando começamos a criar o chat Top, esqueci de mencionar alguns detalhes. Primeiro de tudo, precisamos adicionar mais alguns nomes de classe e vai ser esta era para Element. Então vamos colocar o nome da classe e vamos colocar o texto desaparecer para evitar o excesso de impostos se for muito longo. E então vamos adicionar os sinalizadores de exibição e alinhar o Centro de Itens para garantir que, quando estamos em dispositivos móveis, este Aiken e texto estão centralizados verticalmente, direita e também mais um detalhe. Se abrirmos a sala para Betty Inamoto, usamos o seletor de contexto, então para fazê-lo funcionar, também precisamos esfregar o elemento em torno de mamífero. Isso é o que nos esquecemos de diligir. Então vamos colocar memorando aqui na parte inferior e também vamos importar de reagir Agora use contexto. O seletor funcionará como esperado. Tudo bem, vamos seguir em frente e vamos começar com Chad Bottom. Vamos navegar Teoh Index Dodgy s dentro da pasta inferior. E aqui vamos definir nosso mercado para Primeiro de tudo, vamos colocar em grupo e dentro deste grupo de entrada, vamos colocar a entrada real com espaço reservado, certo? E você mensagem aqui e três pontos no final. Ao lado desta importação, vamos despejar um elemento de botão. Então, vamos definir o botão Importar Grupo Dar. E este botão terá cor azul e aparência Primária dentro deste grupo celeiro, vamos derramar. Eu venho e posso vai ser enviado. Tudo bem, vamos dizer esperar e vamos ver, o que temos? Então agora temos essa importação e temos o fundo. Então, quando clicarmos neste botão, a mensagem será enviada. Muito bem, agora, vamos definir a nossa funcionalidade. Então, em primeiro lugar, precisamos de estado. Então vamos criar importação e disse em pobre, e por padrão ele será definido para um encolhimento vazio. Em seguida, precisamos especificar no manipulador de alterações para no evento de mudança para a nossa importação. E também precisamos associar nossa opinião com o estado real. Então vamos definir o valor. Vai ser importador. E para um evento de alteração, vamos especificar na alteração de importação. O Heller. Vamos definir isso na alteração de importação e podemos otimizá-lo com antecedência onde eles usam callback porque temos o estado de entrada que muda com freqüência e na alteração de importação não terá qualquer dependência. Então este evento inalterado nos dá valor como o primeiro argumento e evento. Então precisamos obter o valor real a partir daqui, e então vamos chamar disse, importar com valor. E só para mencionar que porque usamos essa entrada que vem do nosso terno como um componente , é por isso que recebemos valor como o primeiro argumento. Em qualquer outro caso, receberemos apenas o objeto do evento. Agora precisamos adicionar funcionalidade ao nosso botão para realmente enviar a mensagem. Então é por isso que vamos especificar uma nova função que vamos nomear em Send Click. Ele vai ser o nosso manipulador para no clique Evento neste botão. Então vamos pacificar. Então foran clique, vamos derramar em enviar clique E primeiro de tudo, aqui vamos fazer uma verificação simples Se eu estivesse no porto. Se a nossa mensagem não está vazia, então vamos especificar importação ponto guarnição é igual a mensagem vazia. Se for o caso, então simplesmente sairá da disfunção. Em seguida, precisamos montar a mensagem. E no futuro também teremos mensagens arquivadas. Então, para isso, vamos criar uma função comum que será chamada para montar a mensagem para que ele irá anexar propriedades comuns à nossa mensagem. Então, aqui no topo, vamos criar nova função que vamos nomear, montar, mensagem, mensagem, e como um argumento ele vai receber perfil de usuário. E vamos dizer Chad, eu d ok, e então ele vai nos dar um objeto com o quarto i d que vai ser verificado, I d. Então teremos objeto autor e aqui vamos de dados normalizados antes de continuar. Deixe-me explicar a estrutura que teremos. Então, se abrirmos nosso banco de dados agora, temos salas e perfis e nossos dados agora são planos e muito fáceis de gerenciar. No entanto, agora temos salas e precisamos criar mensagens. Como podemos abordar isso? Podemos, obviamente, colocar mensagens dentro deste objeto, No entanto, com dados em tempo real baseados porque somos inquéritos limitados, precisamos decidir sabiamente sobre a nossa estrutura. Assim, com base de dados em tempo real, é realmente importante manter a estrutura o mais plana possível. Isso significa que, idealmente, não queremos criar objeto aninhado. Então é por isso que vamos criar outro Vamos ver, rota objeto que vamos nomear mensagens e insight. Vamos colocar os dados da nossa mensagem e, em seguida, referir-nos que esta mensagem pertence a esta sala em particular. Nós vamos especificar o quarto que eu d dentro desta mensagem. E também vamos de Normalized Data de Normalização significa que vamos copiar e duplicar nossos dados. Isso é para evitar a realização de várias consultas em nosso banco de dados quando precisamos exibir algo. Por exemplo, bate-papo com mensagem de bate-papo. Também queremos exibir o nome do perfil do usuário, Avatar e outras coisas. Então, quando mostramos a mensagem, se não duplicarmos dados, precisamos enviar uma segunda solicitação para nosso banco de dados e obter o perfil de perfil real. Então, para evitar a realização de várias solicitações, vamos duplicá-lo. Então isso é normal em nenhum banco de dados SQL. Vamos lá. Então, para montar mensagem para autor, vamos derramar nome que vai ser perfilado o nome então vamos derramar também o seu i d , que vai ser perfil seu i d então criado em vai ser perfil criado em, e também precisamos derramar avatar condicional. Então, se você não tem nenhum árbitro, nós não colocá-lo dentro deste objeto para isso. Vamos derramar três pontos. Então vamos ter um perfil ruim do Avatar, e vamos perguntar se o dom existe. Então vamos colocar a chave do avatar com o avatar da porta do perfil. Então, caso contrário, vamos derramar um objeto vazio. Então, quando o avatar do perfil existe, vamos especificar este objeto. E porque fora de três pontos, não podemos espalhar este objeto para este objeto global. Assim, desta forma, ele irá anexar esta propriedade a este objeto. Caso contrário, espalharemos o objeto vazio, que não adicionará nada. Ok, então próximo seu autor, vamos adicionar, criado em e aqui vamos especificar firebase. Mas vamos importar em primeiro lugar. Deixe-me colocar base de importação fogo do aplicativo firebase, e ele vai ser valor de servidor de banco de dados firebase. Carimbo de data/hora Muito bem, agora, vamos usar esta mensagem de montagem e vamos colocá-la aqui. Então, vamos criar um novo disponível que irá nomear dados de mensagens. Então vamos ligar, montar mensagem com o perfil e o Chad I D. Então vamos conseguir o perfil do nosso contexto. Então vamos perfil pobre de usar perfil Gancho que temos de contexto perfil, usar perfil. E também, precisamos de ter uma ideia de chat. E podemos obtê-lo com a ajuda fora usar Paramus que vem de reagir programas de juventude Router . Tudo bem, bom. Agora, para os dados da mensagem, precisamos anexar o texto da mensagem real. Então aqui, vamos pacificar a mensagem. Texto de dados vai ser a nossa entrada. Tudo bem. E agora a coisa é que precisamos executar uma operação atômica para atualizar dados em vários lugares dentro do banco de dados com base de dados em tempo real. É muito fácil de fazer, e eu realmente amo isso. Espere. Então, o que vamos fazer? Vamos criar uma nova mensagem dentro caminho mensagens. E também, vamos atualizar os quartos. E aqui vamos colocar outro adereço, nome vegetal, última mensagem. Esta é para exibir a última mensagem aqui dentro desta lista de salas de bate-papo. Tudo bem, então o que vamos fazer, vamos criar um novo objeto. Será um objeto vazio por padrão, que vai ser atualizações. E a lógica será a próxima dentro deste objeto que modelamos nossos dados de atualização dentro do banco de dados relacionado Lee para a rota fora do banco de dados. Então, teremos a passagem de atualização como uma chave. E para esta chave, teremos os dados atuais atualizados, e então vamos chamar essas atualizações para a rota fora do banco de dados, e ele irá executá-lo como uma operação atômica. Eu realmente gosto desse jeito. Então o que eu quero dizer é que primeiro nós precisamos definir uma nova mensagem que eu d com antecedência. Então, para isso, vamos criar nova mensagem variável I d. Aqui. Vamos colocar o banco de dados. Desta vez será o banco de dados que vem de Deixe-me novamente, como importá-lo, certo? Não funciona. Vamos fazer isso manualmente. Então vamos importar banco de dados do MISC. Muito bem, vamos voltar para as pastas. Certo, mais um nível. Base de fogo Misc. Tudo bem, Perfeito. Então, banco de dados, então nós vamos precisar especificar referência para nossas mensagens. Em seguida, vamos empurrar chão, e então vamos ficar manter desta forma que podemos obter e chave única do banco de dados de tempo Riel sem criar o documento real. Ok, Agora precisamos atualizar este objeto de atualizações. Então vamos colocar atualizações e nossa primeira propriedade será mensagens. Então nós vamos especificar a mensagem que eu d aqui. E para esta mensagem, eu d. Nós vamos pacificar dados da mensagem do segundo objeto vai ser salas, barra chat I D e barra última mensagem e para última mensagem, vamos pacificar todos os nossos dados de mensagem e também Em cima disso, nós vamos anexar mensagem i d. Então mensagem I d vai ser mensagem que eu d como esta. Agora precisamos atualizar o banco de dados real. Então aqui, vamos colocar para tentar, pegar bloco, e aqui vamos chamar uma espera e vamos converter disfunção Teoh uma função de pia. Vamos ligar para a nossa base de dados com o Treff. Então nós obtemos referência à estrada fora do nosso banco de dados sem especificar o caminho, então o que vai chamar atualização e nós vamos passar nosso objeto de atualizações, e ele vai pico Todas as atualizações passadas de Keys, e ele vai atualizar esses passados dentro o banco de dados logo após nossos dados serem atualizados. Vamos chamar o set input para uma string vazia novamente, e também colocaremos um erro de porta de alerta e vamos especificar alguma mensagem de doca, ok? E também talvez vamos definir o estado de carregamento. Então, ao lado desta importação, vamos criar está carregando e triste está emprestando, que será definido como false por padrão. Então vamos chamar disse está carregando antes de fazermos qualquer tarefa assíncrona. No caso de falharmos, vamos chamá-lo de Satya Falls. E quando terminarmos, também vamos chamar False. Agora vamos usar dis loading state para este botão. Então vamos colocar o Onley desabilitado quando nossos dados estão carregando agora, talvez vamos salvar e vamos dar uma olhada. O que você tem? Então, se eu enviar qualquer mensagem para o banco de dados, eu tenho permissão esta noite e isso é porque nós não especificamos nenhuma regra de segurança. Vamos navegar para as regras. E então vamos copiar tudo isso. Vamos colá-lo aqui no fundo. Vamos renomeá-lo para suas mensagens e vamos especificar mensagem I d Vamos salvá-lo e vamos sincronizá-lo com nossas regras locais. E agora vamos tentar enviar uma nova mensagem. Então, se eu clicar agora, vamos abrir nosso banco de dados e aqui eu posso ver um novo caminho, que é mensagens que eu tenho chave recém-gerada, que é na verdade esta mensagem que eu d que nós criamos com esta linha de código. Se abrirmos aqui, criamos em pertencer guisado Esta sala I, d autor texto, é a próxima pessoa e dentro de quartos. Se abrirmos agora, também perdemos uma mensagem, que é essa mensagem que enviamos. Então, parece muito bem. A única coisa que eu quero fazer aqui é na verdade eu quero talvez em um novo manipulador para on key down evento. Então, quando também clicamos em Enter Button, a mensagem está sendo enviada. Então, para esta importação, vamos também colocar em chave para baixo evento e vamos especificar na chave para baixo manipulador, Vamos colocá-lo em seguida, Teoh na mudança de entrada. E isso em Qi para baixo vai ser Ou talvez vamos colocá-lo aqui na parte inferior, ao lado de on enviado clique dentro na tecla para baixo. Vamos receber um objeto de evento desta vez, e vamos perguntar se evento Kiko ou igual a 13. Se o nosso botão que pressionamos é enter, em seguida, primeiro vamos chamar evento prevenir padrão para evitar qualquer funcionalidade padrão definido para este botão. Então nós vamos chamar no clique enviado. Tudo bem, agora, vamos tentar mais uma vez se eu disser olá de novo. Se eu clicar em digitar a mensagem direita foi enviada e o banco de dados foi atualizado. Então acho que é isso. Vamos terminar este vídeo. Vamos comprometer todas as nossas mudanças chamando de bom em tudo. Em seguida, obter commit e, vamos especificar criado fundo carbonizado Mensagens enviadas para o de chat. Esplêndido. Vejo-te no próximo. 124. Exibição de última mensagem na lista de sala: Olá. Agora que temos mensagens dentro do nosso banco de dados e temos apenas propriedade mensagem disponível em dados da sala de bate-papo, podemos exibir esta última mensagem dentro da lista de sala de bate-papo Dentro elemento sala. Vamos fazer isso. Vamos navegar de volta para o código e vamos abrir componente item sala aqui no topo, onde nós d estrutura em torno de propriedades. Vamos também d estrutura última mensagem do que primeiro aqui dentro do tempo atrás, em vez de exibir você data criada em Vamos perguntar, se perdemos dados da mensagem, então vamos exibir nova data fora da última mensagem criada em então quando esta mensagem foi criado. Caso contrário, vamos mantê-lo como estava antes de vamos exibir quando a sala foi criada, então aqui abaixo, onde não exibimos mensagens. No entanto, em vez disso, vamos má renderização condicional. Então, se tivermos a última mensagem, então vamos exibir a última marcação da mensagem. Caso contrário , será como antes. Vamos mostrar espaço. Sem mensagens ainda. Então, dentro deste fragmento de reação, vamos colocar o primeiro usuário Avatar e, em seguida, a mensagem real. Então esta definição vai ser rapper para o componente de avatar de perfil que criamos mais cedo, como você se lembra. Então vamos importá-lo e para adereços. Vamos especificar fonte vai ser a última mensagem. Vamos dar uma olhada. Última mensagem Filha autor Nora al atar ponto autor Senhor Avatar Nome no caso se Avatar não está definido vai ser última mensagem Autor ponto nome e tamanho vai ser fumaça. E para este surdo vamos derramar para exibir Flex e um centro de itens de linha. Certifique-se de que o elemento avatar é 10 para ler verticalmente. Em seguida, você decide se vamos nos livrar desta casca para reagir fragmento ao lado deste avatar perfil . Vamos exibir outro surdo com tags de nome de classe desaparecer para evitar ataques de estouro e margem esquerda. Vamos pôr-te lá dentro. Vamos colocar def. Isso vai dizer última mensagem nome do ponto do autor do ponto. E no próximo ano depois do nome, vamos ficar mal. Última mensagem, texto do cão e em direção ao nome do autor, vamos exibir texto itálico apenas para distinguir entre o nome do autor e a última mensagem. Tudo bem, vamos salvar tudo. Não vamos voltar à nossa candidatura. Posso ver isso inesperado. Tudo bem, então novamente, este fragmento de reagir. Agora, se eu disser o que posso ver, eu tenho a mensagem real. Posso ver o nome do autor. Eu posso ver minha mensagem e eu posso ver minha ninhada Ah. Agora talvez. Vamos tentar uma nova mensagem. Então deixe-me dizer olá do futuro. Se eu enviar esta mensagem, posso ver que a mensagem foi enviada. Agora de novo, meu avatar, meu nome e olá do futuro. Tudo bem, então é isso. Foi bem fácil, certo? Vamos cometer nossas mudanças. Vamos colocar tudo para obter sistema e vamos comprometer dizendo exibir última mensagem dentro do item da sala, na verdade. Vejo você na próxima. 125. Trabalhando com dados desnormalizados: Ei, agora temos uma mensagem de luxúria dentro da lista de estilhaços. Mas aqui está o problema porque nós duplicamos dados agora. Se digamos que eu vá para o meu painel e atualizo meu apelido para outra coisa, vamos salvar para mostrar a aparência 16. Então eles também atualizam meu avatar. Se eu fizer o upload, ele estará sendo carregado. Mas a última mensagem não está sendo atualizada porque esses dados são duplicados dentro do banco de dados. Então precisamos cuidar disso quando atualizarmos os dados reais. Se fizermos algumas alterações, nos certificaremos de que também atualizamos todas as referências que duplicamos. Não vamos voltar ao código e vamos navegar para o painel, Vamos para Dashboard Togo e, em seguida, ir para o painel. E aqui, em vez de este apelido de usuário áspero definir novos dados. Precisamos achar um jeito de atualizar todas as referências. Então, o que eu propus fazer, eu quero propor a criação de uma função auxiliar que irá obter todas as referências dentro do nosso banco de dados, e então nós podemos atualizar nosso banco de dados com antiga referência. Na verdade, será o mesmo que fizemos dentro do fundo do Chad quando criamos este objeto de atualizações e especificamos vários passados para executar uma operação atômica, por isso será basicamente o mesmo. Então podemos chamar essa função assim. Vamos definir como vamos fazê-lo. Então, em vez de um apelido de usuário de peso Raff definido, vamos chamar, Vamos dizer que vamos receber atualizações e porque vamos acessar nosso banco de dados, ele será em uma operação de sentença. Vamos nomeá-lo. Digamos que obtenha atualizações de usuários dentro. Vamos passar Usuário I d que vai ser perfil adoro seu i d. Então vamos passar a chave que precisamos atualizar. Então, no nosso caso, será o nome e, em seguida, passaremos o valor real, que vai ser novos dados como este. Então agora precisamos criar disfunção. Vamos navegar dois ajudantes, ela s e aqui na parte inferior, vamos exportar função de nome problema obter atualizações do usuário. Então ele vai ser qualquer função e ele vai receber usuário i d. Em seguida, ele vai receber chave para atualizar e também ele vai receber valor. E talvez vamos também passar o objeto de banco de dados junto com nossa função. Então aqui vamos passar também este objeto de banco de dados que temos dentro misc lareira apenas por conveniência como esta. Então agora dentro de ajudantes, nós também podemos ter banco de dados aqui. Agora vamos criar um objeto vazio. Atualizações de carvão indefiníveis que a nossa primeira atualização serão o valor real que estamos tentando atualizar para atualizações. Em seguida, irá perfis barra usuário i d que barra chave para atualizar, e ele será definido como valor. Agora precisamos obter as referências reais. Então, nossas referências são Vamos dar uma mensagem de olhar I D. Que autor do que avatar criado em também quartos. Última mensagem. Então, o que vamos fazer? Vamos definir algumas promessas porque existem várias promessas. Não queremos torná-los um por um. Queremos executá-los de uma vez. É por isso que vamos definir nossas promessas. E então vamos esperar todos eles com o ponto de promessa Toda a nossa primeira promessa vai ser receber mensagens e vai ser db dot Ralf dar mensagens, em seguida, para obter mensagens onde digamos que este autor, eu d igual a você nosso usuário, Precisamos primeiro fazer o pedido completo por criança. Então precisamos especificar qual criança. Fomos para referência. Então, em nossas mensagens de referência caso Então nós temos o objeto de mensagem. Então temos autor barra usuário i D. Então vamos colocar ordem por autor barra usuário i d. E então esta chave será igual ao usuário i d. Que recebemos como um argumento e, em seguida, vamos colocar o valor de um para obter o valor real . Então nossa segunda promessa será obter salas de usuários, que serão salas de barra de referência DB. Então, novamente, precisamos colocar ordem por criança. E desta vez, se abrirmos as salas, temos menos mensagem barra autor barra usuário i d. Então vamos menino última mensagem Autor, usuário I d. E então igual ao usuário i d. E novamente uma vez valor. Agora que temos essas duas promessas em estado não resolvido, precisamos resolvê-las. Por esta razão, vamos criar uma promessa de peso que tudo dentro precisamos passar uma série de promessas que vai ser receber mensagens e obter quartos como este e receber mensagens vai nos retornar instantâneo fora mensagens e obter quartos devolva-nos um instantâneo fora dos quartos. Então aqui vamos estruturá-los. O primeiro elemento é obter mensagens. Então vamos primeiro receber mensagem, instantâneo ou mensagens. Camisa de pressão. Um segundo vai ser quartos, camisa de pressão, que vamos nomear correspondente Klay am sequestrador e Air Snapshot. Em seguida, para cada mensagem que temos com a idéia do usuário, vamos chamar para cada instantâneo de mensagem para cada mensagem que recebemos, vamos obter instantâneo de mensagem, e aqui vamos chamar atualizações. Então nós vamos mensagens pobres barra mensagem instantâneo ponto chave, que representa a mensagem i d. Então vamos ter um objeto com todas essas mensagens, e chave vai ser esta idee off mensagem. Tudo bem, então chave de mensagem barra autor chave barra para atualizar. Então, dessa forma, nós referimos mensagens autor eo garoto que queremos atualizar, se é Allah carro nome seu eu d ou criado em. E então para que esta chave seja atualizada, vamos colocar valor e exatamente o mesmo que faremos para o nosso instantâneo. Então vamos realmente copiá-lo. E em vez de m instantâneo, vamos tirar fotos de ar ruim, que é quarto, camisa de pressão e, em seguida, para atualizações, vamos colocar quartos, em seguida, vamos obter a chave de ponto instantâneo quarto, que vai Seja o quarto i d. Então aqui teremos a última mensagem. Em seguida, teremos autor e, em seguida, chave para atualizar com valor. Tudo bem. E logo depois vamos retornar o objeto de atualizações que criamos. Agora vamos dizer o que Vamos navegar até você painel permite e comentou, e vamos realmente importante este objeto de ajudantes, mas parece que ele pode ser importado automaticamente. Então vamos importar obter atualizações do usuário de Vamos referenciar nossos ajudantes misc helpers e parece que não foi encontrado certo, então chegar lá. Atualização. Tudo bem, te levo lá. Atualizações assim. Certo, Perfeito. Agora que temos atualizações, em vez de chamar esta função aqui e em vez de referenciar os dados reais, podemos realmente chamar apenas o banco de dados dot ref porta atualização com atualizações. Então esperaremos e removeremos tudo isso e também tudo isso. Agora vamos salvá-lo e vamos realmente também abrir. Aplaudir Bt, em que carrega o nosso avatar e vamos encontrar a lógica. Então aqui novamente, como então nós ouvimos dentro painel permite copiá-lo e, em vez disso, off novamente a referência ao elemento filho e, em seguida, atualizar como este. Vamos colocar atualizações iria obter suas atualizações do que para perfil i d. Nós vamos atualizar avatar desta vez e Avatar vai ser Não carregue euro assim. Agora vamos remover esta referência. Vamos remover este conjunto de avatar do usuário. Vamos ser apanhados a essa lógica. Vamos colocá-lo aqui e agora vamos dar uma olhada. Se realmente funcionou, vamos voltar ao código. Deixe-me o fresco apenas no caso de eu ir para o painel, se eu clicar em mudar, meu apelido Ok, talvez eu vou dizer olá. Novo nome. Se eu clicar em apelido seguro foi atualizado e eu ainda tenho e para estar aqui. Está bem, talvez me deixes ver o Dashboard 1. O meu tempo. Eu tenho nome aqui. Vamos registrar as atualizações do Cônsul e vamos dar uma olhada. O que há de errado aqui? Se eu inspecionar, eu vou para o console Eu atualizar meu apelido. Recebi este tipo de atualizações, mensagens, perfis, tudo bem, mas não atualizo minha última mensagem. Então isso é estranho. Vamos navegar Teoh ajudantes. E aqui vamos dar uma olhada. Chave de autor para atualizar. Certo, camisa de pressão perdida. Autor, seu I D Vamos verificar nosso banco de dados. Última mensagem. Autor, Seu I D Que é o usuário I d que passamos. Oh, desculpe-me. Aqui não deve ser o último aqui. Deve ser menos mensagem. Vamos salvá-lo. E agora mais uma vez. Vamos mudar nosso apelido. Tiu. Digamos que ela parece 22. Se eu atualizar meu apelido, ele está sendo atualizado aqui. Perfeito. Agora vamos procurar por Al Atar Se eu enviar uma nova imagem novamente, Avatar foi evitado. Vamos olhar lá dentro. Última mensagem. Sim. Ah, O que são foi atualizado? Certo, só para o caso de mais uma vez. Aplaudir. Avatar foi atualizado. Perfeito. Vamos dar uma olhada. Sim, ele foi atualizado, então ele realmente funcionou. Tudo bem. Perfeito. Agora vamos remover a sorte do Cônsul que colocamos aqui e vamos cometer nossas mudanças. É isto. Vamos embarcar tudo para o estado do palco e vamos nos comprometer. Atualize todas as referências de usuário se os dados forem atualizados. Ok. Perfeito. Vejo você na próxima. 126. Exibindo mensagens de bate-bate-: Ei aí. Neste vídeo, vamos exibir mensagens de bate-papo aqui no meio dentro da página de bate-papo. Vamos, vamos navegar de volta ao código e vamos encontrar as nossas mensagens da janela de bate-papo da pasta. E aqui temos togs índice já menos grande, e você arquivo que irá nomear item mensagem. Por enquanto , estará vazio. Então vamos colocar “olá” lá dentro. E vamos deixar assim dentro de mensagens aqui, em primeiro lugar, vamos definir nosso estado que vamos gerenciar com o estado de uso. Então vamos nomear mensagens e mensagens de satélite. E, por padrão, será tal saber. Então também precisamos pegar nosso chat que nós abrimos atualmente. Então, para isso, vamos usar Paramus Hook que vem de reagir rotor e vamos ter criança, eu d agora dentro efeito de uso. Vamos fazer uma ligação para o nosso banco de dados. Primeiro, vamos pegar nossa referência ao caminho do chat dentro do banco de dados, que são mensagens. Então vamos mensagens ruins ásperas. Então vamos chamar o banco de dados, mas não o que vem do pacote Firebase um que vem de RGs baseados em fogo. Então, vamos importar essa. Em seguida, vamos especificar mensagens de barra de referência. Agora vamos colocar um ouvinte em tempo real em mensagens de espera que estão relacionadas ao bate-papo aberto . Então vamos ver mensagens pacificantes, Ralf, ordem de porta por criança. E aqui vamos pacificar a sala I D. E esta é uma propriedade que temos em cada mensagem, que é o quarto I.D. I.D. Então isso da idéia será igual ao chat i d que recebemos de Paramus. Agora, ele apareceu como uma dependência, então vamos editar. E logo depois disso, vamos colocar um ouvinte em tempo real, então vamos colocar valor e honrados pacificar o retorno que vai receber instantâneo. Agora, como você se lembra, este instantâneo será um objeto onde cada chave é mensagem I d. e então nós obtemos os dados reais. Então precisamos transformá-lo. E nós já fizemos isso com a transformação para matriz com a função I d. Então vamos chamá-lo mais uma vez. Então vamos dados pobres e, em seguida, vamos colocar transformar em matriz com i d. Em seguida, vamos chamar o valor de ponto instantâneo e passá-lo para esta função. E então vamos atualizar o estado com dados como esse e porque é um ouvinte em tempo real . É uma assinatura que precisamos cancelar. Então vamos usar Ah, estamos função de limpeza para efeito de uso. E aqui vamos despejar mensagens, bote e cachorro fora, e podemos especificar o valor. Assim, vamos cancelar a assinatura de todos os ouvintes em tempo real nesse caminho. Muito bem, agora, o nosso próximo passo é realmente exibir dados. E primeiro, precisamos obter alguns valores de bullying que nos ajudarão a renderizar nossas mensagens condicionalmente . Então o nosso primeiro será disparado vazio e carbonizado. Vazio vai ser apenas quando temos mensagens definidas e, em seguida, mensagens ponto comprimento é igual 20 Então nós carregamos todas as mensagens, mas não há mensagens em tudo. Certo, então nós também podemos ter pode mostrar mensagens que indicarão se podemos renderizar nosso item de mensagem que criamos. Então, se tivermos mensagens e mensagens, o comprimento do ponto é maior que zero. Então nós poderíamos colocar essa condição diretamente aqui dentro de nossa marcação, mas só para ser mais legal, você sabe, nós colocamos aqui. Então, dentro desta definição, vamos colocar a próxima lógica. Em primeiro lugar , não vai ser uma diferença. Vai ser um U L. Então o nome da classe vai ser lista de mensagens e também os costumes crescem que dentro vamos derramar é carbonizado vazio. Então vamos mostrar um elemento aliado porque temos você, eu e vamos dizer sem mensagens ainda. E então, se pudermos mostrar mensagens, então vamos derramar mensagens, Doc mapa e vamos mapear cada mensagem para item de mensagem. Vamos abrir para um item de mensagem de inteligência. Ele vai ser a porta da mensagem i d. E então vamos passar a mensagem com uma mensagem como essa Agora dentro da mensagem precisamos de estruturar esta propriedade. Então vamos colocar mensagens e aqui no nível inferior D estrutura de mensagens, mas não de mensagens. Desculpe-me da mensagem. Vamos mudar o nome para mensagem. Vamos salvar o que também é alterado na mensagem. E a partir desta mensagem vamos destruir o autor problema D estrutura criado em e vamos destruir texto. Agora ele vai ser um elemento l i e terá o nome da classe fora separado e margem inferior um. Então colocaremos Dave aqui. Essa será a parte superior da nossa mensagem. E então vamos colocar outro def. E dentro deste diferente vai colocar espaço que irá exibir nossa própria mensagem detecta e nome da classe vai ser Ward quebrar tudo para evitar que o texto de estouro se for muito longo. Então, para a nossa parte superior, vamos especificar o nome da classe fora exibir bandeiras alinhar itens fonte central vai ser mais ousado e margem inferior um, então aqui vamos derramar Primeiro perfil Avatar, Vamos abri-lo. Perfis todos Matar. E agora vamos usar inteligência para importar. Então, como fonte, estamos ficando mais baratos. Autor dot avatar para nome. Vamos nos dar ou ao Doc. Nomeie o nome da turma quatro. Vai ser margem esquerda. Um tamanho vai ser excesso. E, em seguida, ao lado deste avatar, vamos colocar elemento Spawn se vamos exibir o nome e o nome da classe vai ser margem esquerda para e depois que lombada irá exibir quando esta mensagem foi criada. Então vamos colocar o tempo atrás. Então vamos abrir o item da sala. Vamos pegar essa importação fora tempo atrás. Vamos colocá-lo na costeleta. Vamos ligar para a mesma hora atrás e colocá-lo aqui em vez desta data. Hora que mostraremos. Apenas criado em e para o nome da classe para normal e texto preto. Vamos mantê-lo como está, mas também vamos mostrar margem esquerda para quem? Foi muito. Agora vamos dar uma olhada. Como podem ver, temos as nossas mensagens. E agora, se eu digamos, executando sua mensagem, vamos dizer oi lá. Você pode ver que ele apareceu aqui. E também é aparecido aqui dentro da última mensagem. Então agora nós realmente temos nossas mensagens sendo exibidas. E funcionará também para qualquer outra sala de bate-papo. Vamos dizer olá daqui. Agora temos uma mensagem aqui. Está bem. Perfeito. Então, este é um vamos cometer nossas mudanças. Vamos esquecer tudo. Vamos colocar, se comprometer. E as pessoas nomeiam mensagens exibidas dentro da página de bate-papo. Muito bem, vemo-nos na próxima. 127. Exibição de dados de perfil de usuário: Olá. Neste vídeo, vamos adicionar uma nova janela modelo. Então, quando clicamos no nome de usuário de alguém, podemos observar o perfil do usuário. Não vamos voltar ao código. E aqui na pasta Mensagens, vamos cumprimentar seu arquivo. Nome vegetal Informações do perfil. BT e Moto GS. Vamos criar um novo componente. E por enquanto, vamos mantê-lo vazio. Vamos abrir o item da mensagem. E aqui, em vez do elemento span onde exibimos o nome do autor, Vamos exibir perfil em para BT e Moto e para este componente porque precisamos obter dados do usuário , precisamos exibi-lo dentro. Passaremos o perfil e passaremos. Apenas autor e tudo o resto será gerenciado de dentro do componente. A partir daqui, vamos destruir o seu perfil por enquanto e vamos definir o mercado. Então, primeiro de tudo, vamos colocar botão e este botão vai dizer nome curto fora do nosso usuário. Então vamos criar novo viável aqui que vamos nomear nome curto e ele vai apenas jogar em Lee o primeiro alcunha afastado. Então, se é um nome completo como primeiro nome segundo nome, vamos exibir apenas o primeiro nome. Então vamos colocar o nome do trabalho no perfil. Então vamos dividi-lo com espaços vazios e então vamos pegar o primeiro elemento. Agora vamos exibir apenas o primeiro nome porque ele vai ser modelo. Também precisamos de um estado mortal. Então vamos usar o nosso gancho, que é usado estado modelo. Aqui vamos receber está aberto, fechado e aberto. Muito bem, agora ao lado deste corpo e vamos servir modelo. E dentro deste modelo, vamos primeiro definir a propriedade do show que vai ser aberto e no esconderijo vai ser roupas do que dentro desta moto. Teremos uma filha mortal, Heather, como sempre. Então teremos corpo e teremos rodapé como este. Então, dentro de Heather teremos o título da porta mortal e dentro do título moral vamos exibir o perfil do nome curto, então dentro do corpo ou talvez dentro do rodapé, fundo da exibição da bolha que vai ser um elemento de bloco no clique Ele irá fechar nossa moto e será apenas sobre apenas para fechar este mortal do que dentro do corpo. Primeiro vamos colocar a classe Nome fora do centro de texto, então dentro de uma bolha pobre exatamente a mesma imagem de avatar que fazemos em Avatar. Um BT de sangue em que é sim, este avatar perfil. Então vamos copiá-lo e colocá-lo aqui. Agora vamos importar o perfil Avatar. E ao lado dele, vamos exibir H quatro onde vamos exibir o nome completo desse usuário. Então vamos primeiro pegá-lo. O Const. O nome vai ser retirado do perfil. E talvez vamos também pegar Avatar e vamos dizer criado em Então agora nós não precisamos Teoh a estrutura ou nós não precisamos especificar perfil aqui. Então, para esta idade, para nós vamos derramar margem conversa para adicionar alguma margem no topo. E então vamos exibir membro desde e, em seguida, vamos derramar membro desde variável que vamos criar. Então vamos pobre membro const desde e vamos colocar nova data criada em e, em seguida, vamos simplesmente chamar para cadeia dia local para ex-nossa data. Não. Então não usamos aberto. Então vamos colocá-lo para isso no clique. Ok, bom. Agora vamos abrir o item da mensagem. Parece bem. Parece bem. Agora vamos dar uma olhada. Então, como podem ver agora, temos o botão. Quando clicamos nele, podemos ver que ela parece 22. Programe nossa imagem, nome completo, cenas de membros e feche Perfeito. Mas eu não quero ser exibido assim. Então, vamos apenas algumas coisas. Então, tudo o resto que será passado para este componente como um prop será redirecionado para adereços de botão. E também, vamos nos livrar desse def como um elemento de rap. Deixe que seja apenas um botão no final, para que todos os adereços sejam passados para este botão. Então vamos espalhar Bt e adereços objeto sobre este componente assim. Então, para este perfil em quatro batidas e modelo, podemos passar aparência, que vai ser link. E também podemos passar o nome da classe. Vamos adicionar estofamento. Zito Dan. Vamos adicionar margem esquerda e também texto preto. Vamos guardá-lo e vamos dar uma olhada agora. Parece bom. Se eu tenho ou eu posso ver que é algo que clicável. Se eu clicar nele, posso obter dados do usuário. Está bem, Perfeito. Então é isso. Agora vamos cometer nossas mudanças. Obter tudo, obter commits. Digamos que os dados do usuário exibidos com janela maro. Muito bem, vejo-te no próximo 128. Adição de presença em tempo real - parte 1: Olá. Neste vídeo, vamos gerenciar a presença do tempo do rial em nossa aplicação com base de fogo. É muito fácil de fazer. Vamos descobrir como podemos lidar com isso. Vamos ao Google e vamos digitar Firebase Riel Time Presence. Então podemos ir para o primeiro link construído presença e loja de fogo nuvem. E aqui já temos uma solução usando presença em banco de dados em tempo real. Então nós precisamos apenas pego ser este trecho de código e, em seguida, usá-lo em nossa aplicação. Então vamos primeiro copiar está offline e on-line para objetos de valor do banco de dados e vamos navegar para o contexto do perfil. Este é o lugar onde vamos lidar com tudo, porque aqui podemos ter acesso à autenticação. Objeto com assinatura em tempo real. Tudo bem, então vamos colocar apesar de um bles aqui no topo, e vamos substituir Var por Constant. Agora vamos dar uma olhada. O que precisamos fazer a seguir? Precisamos adivinhar o banco de dados com informações conectadas. Então, isso é como uma maneira geral no caminho do banco de dados que podemos acessar e podemos obter presença em tempo real fora atualmente assinado no usuário. Então vamos apenas copiá-lo. Ou talvez vamos copiar tudo isso assim, e vamos colocá-lo aqui dentro. Se objeto de autenticação, Denver executará nosso gerenciamento de presença em tempo real. Então aqui precisamos obter referência a interligados em vez de banco de dados Firebase. Vamos usar a base mais tarde que temos dentro misc. Base de fogo. Então nós temos referência para inferir conectado no valor que é convertido em uma função estreita do que nós recebemos. Snap. Claro, se instantâneo esse valor for falso. Vamos pobres e três pessoas igualdade do que o status do usuário. Referência do banco de dados Então vamos dar uma olhada. Isto é tão valioso que podemos copiar. E este é o lugar literal armazenar nosso status dentro de nosso banco de dados em tempo real. Então, o que precisamos fazer, porque vai ser uma assinatura em tempo real, precisamos também cancelar a assinatura dela no futuro. Então vamos colocá-lo aqui dentro Yousef agir como um novo viável vamos chamá-lo usuário startles banco de dados áspero. Vamos remover o banco de dados e vamos apenas colocar o status do usuário, ref. Em seguida, vamos atribuir usuários iniciantes ref para o status do banco de dados Ralf e você idéia, Vamos colocá-lo aqui no topo, assim como, e em vez de você idéia. Vamos usar o seu i d e substituí-lo pela interpolação de cordas. Então vamos ter ambos objeto dot seu i d como este, então, porque é uma assinatura. Quando somos olhados para fora. Vamos verificar se temos o status do usuário. Árbitro, se tivermos feito isso, vamos cancelar a assinatura dele. E o mesmo que faremos para nossa função de limpeza sobre estudos de usuários de heróis. Rough off. Certo, perfeito. Agora vamos gerir esta parte. Então, vamos remover todos os comentários. Vamos remover tudo isso. E aqui vamos colocar o usuário começou a cinta. desconexão está offline para banco de dados e, em seguida, função. Vamos converter-nos para uma função adulta. Então vamos substituí-lo pelo seu status. Ref. Sad está online para banco de dados, então é basicamente isso. Agora vamos dar uma olhada. Temos fogo. Base não está definida. Vamos dar uma olhada. Base de dados Firebase. Tudo bem. Menos base de fogo de importação do aplicativo firebase para que possamos obter acesso ao valor do servidor. Tempos temporários. Vamos guardá-lo e vamos dar uma olhada. Agora, se estivermos lá dentro, temos permissão negada. Isso é interessante. Deve ser algo com regras de segurança. Então vamos dar uma olhada onde escrevemos nossos dados. Uh huh. Exatamente. Então nós escrevemos nossos dados para cortar o status de você I d. Então vamos novamente corrigir regras de segurança para este banco de dados passado dentro. Então, temos status. Então vamos chamá-lo de “este caminho”. Faremos assim. Então aqui teremos o usuário I d. e então seremos capazes de escrever para esses lugares em Lee. Se nos desligarmos, eu seria igual a usar suas idéias tão maliciosas Copie essa lógica e colá-la aqui assim. Agora vamos guardá-lo e vamos dar uma olhada se realmente funcionou. Se eu para refrescar meu aplicativo, eu posso ver agora que eu não tenho avisos. Então vamos chamá-lo de naves P e vamos cantar os gritos com nossos dados locais como este. Agora vamos navegar de volta aos dados e vamos verificar aqui. Dentro do nosso banco de dados, temos New Path, que é estudos que eu tenho meu usuário, eu d. E então eu tenho menos mudança e fiquei online. Agora vamos dar uma olhada. Se eu sair do aplicativo, eu fiquei online, então isso é porque quando nós sair, nós não colocamos um geológico para o nosso banco de dados, então Onley quando entramos. Deixe-me continuar com o Google e deixe-me selecionar minha conta. Está bem? Estou assinada. Você pode ver que a última alteração foi alterada. Você viu a frota baleada, certo? Então, o que está acontecendo? Que realmente funciona quando entramos, mas não quando saímos. E a coisa é porque nós definimos nossas regras de segurança dessa forma, nós podemos escrever e ler em Lee quando nós temos fora de você I d. Então, quando nós registramos nosso de nosso aplicativo quando nós sair, este objeto autor será definido como agora, Então isto será disparado. E se colocarmos nossa lógica aqui quando sairmos dessa maneira, teremos permissão esta noite porque no momento, quando tentaremos direitar-nos para o banco de dados do objeto será definido como agora. A solução aqui é apenas ir para o painel. Vamos ao Dashboard Tuggle aqui. Precisamos derramar essa lógica. Então, logo antes de sair do Mobile direto para o banco de dados. Então ainda temos acesso às nossas regras de segurança. Então ainda podemos ter acesso ao objeto autor. E só então vamos sair do nosso usuário. Então, qual lógica deve ser colocada aqui exatamente o mesmo que despejamos aqui dentro iniciadores de usuários. Refs, isto é. Ah, voando em busca de dados. Então, o que eu propus a você daqui em diante, nós vamos exportar o CONST. É um vôo para banco de dados. Então vamos copiar essa lógica. Então, logo antes de sair do nosso aplicativo, vamos colar essa lógica. Então vamos importar está offline para banco de dados. Então vamos colocar o banco de dados Dodds Ralf, então vamos colocar status que barra. Então vamos mudar as citações e pique nosso usuário atual. Eu d então nós vamos derramar set, e então nós vamos definir um vôo para o banco de dados algo como isso em Lee, então porque é uma promessa. Então, vamos fazer por aqui. Só então vamos sair do nosso usuário. Vamos alertar o nosso utilizador, e vamos fechar a nossa candidatura. E no caso de algum erro, nós também vamos notificar nosso usuário, mas melhor. E vamos dizer uma mensagem melhor. Tudo bem, agora, vamos realmente dar uma olhada. Então deixe-me atualizar o aplicativo só por precaução. Vamos dar uma olhada no banco de dados. Agora temos o status online, e se eu sair, estou desconectado. E agora fiquei fora da linha. Então, muito legal agora se eu assinar novamente, eu estou conectado e status foi alterado. E agora, se eu fechar meu aplicativo, se eu fechar minha guia, eu posso ver o estado é um vôo, então ele realmente funciona. E é isso. Então é assim que ele pode ser tratado com o aumento de fogo. Foi bem fácil, certo? A única coisa aqui que eu quero fazer é que eu quero realmente cancelar a inscrição também de referenciado ou info dot connect quando estamos assinados fora. Então vamos sair quando estivermos assinados o nosso e também vamos colocar o mesmo para a função de limpeza só por precaução. Então, desta forma, lidamos com todas as assinaturas em tempo real e tudo funciona bem. Bem, isso é tudo para este vídeo. Então, vamos nos comprometer. Nossa mudança vai adicionar tudo ao estado do palco. E então eu vou cometer tudo com mensagem. Eu vou dizer uma presença de tempo riel, ouvinte para um usuário. Perfeito. No próximo vídeo, vamos exibir uma presença em tempo real para os usuários dentro da janela de bate-papo. Vejo você lá 129. Adição de presença em tempo real - Parte 2: Ei aí. Neste vídeo, vamos exibir presença em tempo real para cada usuário que vemos no chat. Ele será exibido como um dar na frente do usuário Avatar. Vamos antes de começarmos com isso. Quero salientar que no vídeo anterior, quando conseguimos a presença em tempo real para cada usuário aqui, fizemos essa comparação. Se o valor do instantâneo de igualdade tripla for igual a falso, então isso não é completamente correto porque esse valor pode não ser um boliche. Então, para evitar isso, vamos colocar negação dupla para convertê-lo em uma linha de boliche. E agora tudo ficará bem. Tudo bem, agora vamos começar. Então, o que precisamos para ir primeiro? Vamos criar um gancho personalizado que nos dará a presença de usuários particulares. Então, vamos navegar para ganchos personalizados. E aqui na parte inferior, vamos exportar e você funciona, que vai ser usar presença. E este gancho receberá o usuário I D. que queremos tirar a presença. Então vamos criar nosso estado para a presença. Vamos nomeá-lo presença e dito presença. Ele vai ser estado de uso simples, que por padrão, será dito para saber. Então dentro de você o fato de que vamos extrair nossos dados de usuário. Então primeiro precisamos obter referência. Então vamos grande gráfico de status do usuário const ia ser banco de dados de firebase dot treff seguida, começou um status ruim cortar seu I d que temos como um argumento, então precisamos derramar uma matriz de dependências do que precisamos passar o seu i d dentro. Então nós vamos pobre status de usuário Rough Dar no valor. Então vamos encurtar, e logo depois disso, vamos verificar se o instantâneo existe. Então, se houver algum registro dentro do banco de dados para este caminho, então vamos derramar dados const igual valor de ponto instantâneo. E então vamos definir presença para dados, tudo bem. E dentro da função de limpeza, vamos cancelar a inscrição do status do usuário Raft, início do usuário. É áspero. E a partir deste gancho, vamos voltar a presença, certo? Perfeito. Parece bom. Agora, vamos criar um componente que será um ponto onde vamos exibir a presença do usuário. Então vamos para os componentes. E aqui menos grande. Você arquiva a presença de nome vegetal pontuando os Gs então dentro deste componente vamos chamar nosso cozinheiro personalizado, que é usar presença. Então vamos má presença const é igual a presença de uso. E nós vamos passar o seu I d. que vai receber como um adereço para este componente como este. Então, dentro da marcação, vamos colocar a próxima, vamos abrir a documentação do traje. Então vamos procurar a dica da ferramenta. Vamos abri-lo. Vamos encontrar um exemplo de acionar eventos pairando. Então precisamos exatamente dessa funcionalidade. Vamos para exemplos e vamos copiar esse. Então, dentro do nosso tribunal, vamos colocá-lo assim. Vamos importar sussurro do nosso vidente e em vez de botão, vamos exibir um lote e dica de ferramenta não vai ser esta dica de ferramenta. Vai ser este componente. Vamos copiá-lo e vamos baseá-lo assim. Agora precisamos também importar a ponta da ferramenta e dentro da ponta da ferramenta. Não vamos colocar nada. Por enquanto, no entanto, ele diz que o componente vazio nós mesmos fechando e você está bem dentro. Nós vamos colocar distintivo também do nosso terno e dentro do lote Bem, na verdade não colocar nada. Será apenas um dardo de alguma cor. Então agora precisamos obter o que vamos colocar dentro da ponta da ferramenta. E o que vamos colocar dentro do lote que cor irá exibir? Bem, nós realmente precisamos executar alguma lógica, e o melhor lugar para lidar com isso é realmente criar uma função personalizada que vamos chamar a partir daqui. Então, para este distintivo, vamos mostrar o nome da classe fora do carro, senhor. Apontar ela e cor de fundo estilo vai ser obter cor que vamos criar em um momento e dentro vamos passar presença como esta e para dica de ferramenta para o nosso texto. Vamos passar, receber mensagem. E também vamos chamar isso de presença como esta. Então agora precisamos criar essas duas funções, então vamos navegar aqui até o topo. E primeiro, vamos criar “get color”. Vamos receber presença. E primeiro, se a presença é indefinida ou se é agora. Então, se não estiver definido, então vamos retornar uma ótima cor, certo? Então vamos colocar declaração switch e então vamos alternar entre Dar presença. Vamos abrir o nosso estado de ponto de presença de banco de dados. Então, se tivermos caso online, então vamos retornar cor verde. Se tivermos caso fora de mentir, então vamos exibir cor rad e, por padrão, vamos exibir também grande como este. Então, para cor, nós já agora vamos criar isso para texto. Então vamos definir obter texto com presença também. E, novamente, verificamos sem valor. Então, se não temos presença, então não vamos mostrar em nenhum estado. Então vamos voltar a presença dos Estados Unidos. Se for igual a dois online, então vamos voltar online. Caso contrário, vamos retornar a luxúria on-line do que vamos abrir interpolação de cordas do que colocar nova presença de data. A luxúria mudou. Dois encontros locais bebem assim. Está bem, Perfeito. Agora vamos realmente usar este componente. Vamos navegar até o item da mensagem. E logo antes de exibir perfil Avatar, vamos usar presença não. E vamos passar-lhe idee como autor ponto seu I d. Agora vamos dar uma olhada. E, na verdade, se o meu aplicativo agora está na frente do meu perfil, eu posso ver ponto verde e se eu passar o mouse, eu posso ver online. Então, como podemos agora testar contra vários usuários? Bem, deixe-me sair e me deixar olhar com o Facebook para que ele vai criar eu e seu perfil de usuário e nós vamos vê-lo Então agora você pode ver o papai. É estado desconhecido E isso é porque, como você se lembra, no vídeo anterior, nós definimos regras de segurança para status barra usuário I d. que possamos ler Onley nosso usuário atual. Eu d igual a dois usuários I d que estamos tentando acessar dentro de oito sempre. Então agora temos permissão esta noite. Bem, para consertar isso para certo, vamos mantê-lo como está. Mas para os Regionais, vamos nos ajustar e diremos, se não for igual neve em Lee, então seremos capazes de ler os dados dos usuários. OK, agora vamos copiá-lo e sincronizá-lo com nossos dados locais. Vamos dizer onde e agora vamos dar uma olhada. Se eu atualizar meu aplicativo agora, ele ficará bem. E se eu pairar eu posso ver o último on-line nesta data para que ele realmente funciona. E se eu disser olá, posso ver que atualmente estou online e outro usuário está offline. Então é isso e funciona muito bem. Vamos cometer nossas mudanças. Vamos derramar, pegar em tudo terra, nos comprometer e vamos servir esta peça para presença em tempo real, para um fato. Vejo-te no próximo 130. Adição de gaveta: Olá. Neste vídeo, vamos adicionar Drover para chat para cima onde podemos adicionar informações de sala, como quarto, nome e descrição. Vamos lá. Não vamos voltar ao código e vamos encontrar a nossa pasta principal. E aqui dentro do índice de togs foi apenas abri-lo ao lado daquele arquivo. Vamos criar qualquer um que vamos nomear Editar quarto BTM Drover Inside vamos colocar o próximo mercado. Então, primeiro de tudo, vamos usar elemento botão e dentro vamos colocar apenas uma carta que significa admin. Em seguida, o nome da classe vai ser fronteira rádios círculo do que o tamanho vai ser pequena cor vermelha e no clique. Vamos colocar um manipulador aberto que as pessoas pegam de usar o modelo State Hook que usamos muitas vezes. Quanto a agora, então vamos largar está aberto, aberto e fechado. Agora precisamos criar a janela moral. Então vamos saudar de Drover. Vamos importar de RC ou assim dentro deste rover, nós vamos derramar propriedade show que vai ser é aberto do que on. Hyde vai ser roupas e colocação vai ser certo e o mesmo que para modelos. Drover tem Drover Header corpo e por isso vamos criar esses componentes. Dentro do rodapé vamos derramar outro botão que será apenas para fechar o Drover para que seja um bloco elementos e no clique vamos fechar nosso Drover dentro Heather, vamos derramar, dirigiu ou título e para Drover título, Nós vamos despejar a Sala de Edição Tudo agora, na verdade, para Drover Body antes de defini-lo. Vamos realmente usar este componente dentro dos componentes superiores. Então vamos abrir engrenagens de índice dentro da pasta superior e aqui dentro. Mas na barra de ferramentas Vamos usar no quarto VT e Drover, é isso. Agora dentro do nosso corpo iria definir para importar elementos um para o nome do quarto e 14 quarto descrição e nós vamos usar nossa entrada edita ble que usamos anteriormente. Então vamos abrir este componente e então vamos ser importantes. Então, para a entrada de Ed Izabal, precisamos passar o valor inicial. Então vamos pegar essa do contexto atual da sala. Então aqui no topo da placa Blacks, nome é igual a usar sala atual e vamos selecionar o nome do ponto de valor e o mesmo que faremos para descrição. Então vamos pegá-lo. E também, vamos enrolar este componente, mamífero. Então deixe-me colocar um memorando aqui e deixe-me importá-lo assim. Tudo bem? Agora precisamos realmente definir nossos componentes. Então, para editar importação Herbal para a primeira entrada, que vai ser sobre o nome, vamos passar o nome do valor inicial do que devemos fornecer na função segura e deixá-lo ser no nome seguro. Quanto a agora, então vamos colocar rótulo e rótulo vai ser Ahh, seis elementos com classe. Nome fora da margem, dois de baixo. Então vai ser o nome. E também mensagem vazia vai ser chamado Pode ser vazio. Tudo bem. O segundo em pobres vai ser uma área de texto no porto. Então vamos pacificar a classe competente. Ele vai ser a área de texto subiu por padrão será cinco. Então nós vamos derramar também valor inicial como descrição do que nós vamos colocar inseguro, que vai ser na descrição segura e também mensagem vazia vai ser descrição não pode ser vazio. Tudo bem, agora, vamos salvar e definir essas funções. Então, primeiro de tudo, vamos criar no nome seguro, e então criaremos a própria descrição segura. E como nossa funcionalidade é muito semelhante, vamos criar uma função comum que será chamada dentro de cada uma dessas funções. Então, ele vai ser, digamos, atualizar dados de dados de dia, e ele vai receber chave. Ou digamos campo o que precisamos atualizar e também o valor real que será triste para esta chave. Muito bem, agora, dentro do próprio nome Save. Vamos chamar dados de atualização com o nome como uma chave e também novo nome, que vai ser passado como um argumento para esta função porque passamos este manipulador para entrada credível. E como você se lembra, se abrirmos, ele nos dará o valor final. Tudo bem, então o mesmo que faremos na descrição segura aqui, vamos colocar a descrição e o novo. Digamos que a mesa vai ser nova mesa. Então, dentro dos dados, vamos chamar objeto de banco de dados. Então nós vamos especificar referência aos quartos barra sala I D ou chat i d. Então vamos pegar aquele de usar Haram. Então vamos pegar share i d de programas de uso. Vamos má importação para o topo. E, em seguida, para esta referência, vamos especificar criança vai ser conjunto de chaves vai ser valor. Depois disso. Quando terminarmos com a gravação de dados no banco de dados, vamos chamar alerta, e vamos especificar sucesso atualizado com sucesso e vamos colocá-lo por quatro segundos. E no caso de termos algum erro, vamos também disse alerta, mas desta vez melhor. E vamos colocar a nossa mensagem assim. Tudo bem, parece bom. Vamos apagar este espaço vazio. Vamos economizar e vamos dar uma olhada. Agora temos este botão A no topo, à direita. Vamos clicar nele. Temos Drover, e o primeiro problema. Eu posso ver que não temos nenhuma margem aqui, então se nós inspecionamos, podemos ver que se abrirmos o grupo de importação e temos que fazer, Dave está aqui e eles basicamente não têm nenhuma margem. Então vamos abrir nossa importação credível. Então precisamos derramar algum espaço para esta definição, ou pode ser uma opção. Então, o que eu propus a fazer, podemos passar outro argumento para entrada credível, que vai ser o nome da classe ladrão e, por padrão, ele estará vazio. Então vamos passar esse nome de classe rapper para o nome da classe do ladrão e o que vamos fazer, vai dizer com uma maldita navegação, você é uma entrada credível. E para a área de texto começou um nome de fechamento rapper especificar vai ser margem superior três para adicionar algum espaço em cima disso, vamos dar uma olhada. Agora eu posso ver que parece bom. Agora vamos realmente editar alguns dados. Pode ser o novo nome de Roma. E se eu disser onde posso ver bem sucedido, atualizado e nome do quarto foi atualizado. De fato. Ok, frio. Mas há um problema para nós. Lembre-se, com ladrões, eles não são exatamente responsivos. Então, o que precisamos fazer? Precisamos passar toda a propriedade para este robur quando estamos em dispositivos móveis. Então vamos usar o gancho de consulta de mídia aqui no topo. Vamos especificar que o celular dele vai ser usado. Consulta de mídia. E aqui nós vamos especificar marcas com off 99 2 pixels. Então vamos passar. Isso é mais bile para a propriedade completa e será ativado somente quando estivermos em dispositivos móveis . Então, agora, se abrirmos e precisarmos da janela , ainda ficará bem. Ok, então é isso, eu acho. Agora vamos cometer nossas mudanças. Deixe as pessoas tudo para o palco. Estado é sempre e, em seguida, ficar comprometido. Adicionada sala de edição. Drover. Tudo bem. No próximo vídeo, adicionaremos mais segurança à nossa sala porque, como você pode ver, por enquanto, podemos adicioná-lo. Esta sala, mesmo que não estamos admite porque não temos nenhuma permissão de usuário. Então este é o nosso tópico para o próximo vídeo. Vejo você lá. 131. Regras baseadas de acesso e segurança baseados em confiança: Ei aí. Neste vídeo, as pessoas gerenciam nossa segurança baseada em funções em preenchimentos específicos. Quando tentamos adicioná-lo. Informação do quarto, vamos. Então, primeiro lugar, como vamos definir nossos papéis. Se abrirmos nossa estrutura dentro dos quartos, podemos ver que criamos na descrição, última mensagem e nome. Então aqui vamos também adicionar outra propriedade, que vai ser admite. E com base de dados em tempo real, podemos prejudicar uma raça ou podemos. Mas eles são realmente mal gerenciados porque fora de seu pobre sistema de construtor de consultas, porque fora de suas consultas pobres em banco de dados em tempo real, vamos colocar nossos Edmonds como um array fora de ID de usuário. Então, se o usuário pertence a esta matriz, isso significa que o usuário é um administrador e não irá colocá-lo como uma matriz. Nós vamos criar um objeto dentro do nosso banco de dados, e cada chave vai ser usuário i d. E se este usuário é um administrador, então ele será definido como verdadeiro conselho. Este usuário não estará dentro do banco de dados. Certo, então, primeiro de tudo, o que precisamos fazer, precisamos adicionar um usuário aos nossos dados. Vamos para, digamos novo nome do quarto. Ou talvez vamos mudar o nome para algo mais específico. Vamos dizer legal, vamos salvá-lo. E agora vamos navegar através desta base de dados aqui. Vamos adicionar novo campo que vamos criar admissões do que vamos clicar no sinal mais aqui. Então precisamos colocar o nosso usuário I d O que podemos fazer, podemos ir para o contexto do perfil. E então quando saímos do objeto, vamos Cônsul Acusador i d para obter o nosso usuário i d. Então agora eu posso me pegar pelo usuário I d e colocá-lo dentro do banco de dados e, em seguida, sat value to true e, em seguida, editar para os dados da sala Então parece assim. Agora, para restringir o acesso, precisamos definir regras de segurança, então vamos navegar para regras. E aqui vamos fazer a próxima coisa para o nosso caminho quartos. Nós vamos remover a propriedade certa para que ele será pego a partir daqui para que ninguém pode realmente direito dois quartos caminho, mas eles são capazes de ler quartos do que para o quarto I d. Em vez disso, off escrevê-lo assim. Não podemos recriar a regra, mas também para a última propriedade de mensagem, que é assim. Nós nos deixamos pacificar, certo? Regra disse para fora não é igual a Não, deixe-me para lama assim. Isto é devido a, se você se lembrar, quando atualizamos dados em vários lugares, também atualizamos a última mensagem dentro da nossa sala. Então, basicamente, todos os que escrevem para o chat podem atualizar a última mensagem dentro da sala, mas não outros campos como quarto, nome e descrição. Aqui vamos definir modelos para exatamente aqueles sente assim para idee sala, somos capazes de escrever dados primeiro quando os dados não existem. Quando tentamos criar e você quarto, vamos especificar se os dados. Então, esses dados são novamente um objeto global dentro das regras de segurança e representam os dados atuais que estamos tentando acessar. Então, se os dados existem por isso é um bowline foram capazes de escrever para estes passado quando os dados não existem. Tudo bem, Então, quando estamos tentando criar uma nova sala com a sala específica I d, ou se somos um administrador, só então seremos capazes de escrever e editar esta informação. Então, como podemos fazer isso? Então sabemos que armazenamos em adicionar homens, então temos usuário I d e verdadeiro. Com base de dados com regras de segurança, funciona assim. Abri documentação para dados em tempo real, basicamente rituais. E aqui eu confinei essa informação. Se eu rolar um pouco para baixo, eu posso encontrar esta informação que eu posso acessar alguns preenchido usando esta abordagem. Então eu vou usar exatamente o mesmo padrão e o que eu vou fazer. Vou perguntar se os dados que estamos tentando acessar têm admissão de crianças. Então, dentro disso, em Mons Child, temos outro filho que será nosso usuário. E podemos obtê-lo de ambos os objetos. Então vamos perguntar se a criança fora do ponto seu valor i d ponto é igual a dois. Verdadeiro. Então, se tivermos um registro para o nosso usuário dentro Edmunds preenchido, então seremos capazes de escrever para esse caminho. Agora, vamos guardá-lo e vamos dar uma olhada. Agora, se eu sou um administrador deste grupo frio, eu vou clicar nisso. Poderei editá-lo porque editamos nosso usuário I d para o banco de dados. Digamos que algo aleatório agora atualizá-lo com sucesso. OK, agora vamos para outra sala quando não somos administradores, deixe-me tentar editá-la. Olá mundo. Agora, se eu tentar saborear, vou conseguir permissão esta noite, então nossas regras de segurança funcionam e isso é muito legal. E por causa disso agora restringimos o acesso ao nosso banco de dados. Mas também precisamos gerenciá-lo programaticamente precisamos adicionar homens etc. Então vamos também fazer isso. Então vamos navegar para criar quarto, modelo de mão de praia. E aqui a água servirá. Quando vamos criar uma nova sala, vamos adicionar a nós mesmos para adicionar homens. Então aqui, quando definimos em seus, um, dados, nós também adicionaremos um novo objeto adicionado feijão. E nós vamos nos especificar. Vamos importar em primeiro lugar. Sim, ele foi importado do usuário atual, seu I d está definido como true. Agora, sempre que adicionamos em seu quarto, nos definimos como administradores. Depois, quando lemos os dados da sala, precisamos saber quem são exatamente de Adnan. Então vamos navegar para Chatel gs e aqui para uma sala atual. Vamos fazer a próxima coisa porque é um objeto e precisamos trabalhar com I raise Idealmente, quando trabalhamos dentro do nosso código, precisamos transformar este objeto em uma matriz. Então vamos criar aqui. Novos e valiosos anúncios e ajudantes internos. Vamos definir uma nova função que irá transformar nosso objeto em apenas uma matriz. Então vamos nomeá-lo exatamente da mesma maneira que fizemos com esta função. Mas nós vamos dizer, basta transformar em array aqui. Vamos receber valor instantâneo novamente e deixe-me definir teclado função, e esta função será muito simples. Então, se Snapshot 12 existir, então vamos retornar chaves de objeto fora deste valor de snapshot para que vamos obter uma matriz fora ID de usuário. Caso contrário, comece um retorno e esvazie Agora vamos dizer que este ajudantes e vamos usá-lo dentro. Chatterjee está aqui. Vamos nos transformar em matriz. Digamos que a porta atual da sala Adnan e agora temos a administração. Mas também queremos saber se estamos atualmente conectados usuário é um administrador. Então o que? Nós viemos até você. Podemos criar um novo valioso é administrador e vamos simplesmente perguntar se admissões inclui fora que o usuário atual ponto seu i d e como podemos passá-lo esses dados junto com o contexto. Então vamos passar, admite e é admin. A partir de agora, seremos capazes de exibir este drover Onley quando formos admitidos. Então agora vamos navegar Teoh nossa parte superior. Vamos navegar para indexar togs dentro da pasta superior e ouvir do contexto. Vamos pegar seu administrador usar o valor atual da sala. Valor é administrador assim. E agora vamos perguntar se somos um administrador Onley, então vamos exibir em seu quarto Bt e Drover. Agora vamos dar uma olhada dentro desta primeira sala onde somos o administrador. Podemos ver esse Drover, e somos capazes de adicioná-lo. Informações do quarto atualizadas com sucesso. Mas na sala onde não estamos admite, não seremos capazes de ver este Drover. E também não seremos capazes de atualizá-lo porque dissemos regras de segurança. Vamos copiar as regras de segurança. E vamos sincronizá-los com os locais de guerra. Vamos abrir regras de base de dados e colá-las aqui. Tudo bem. Parece bom. Que haja mais uma coisa nas nossas regras de segurança. Se inspecionarmos nosso conselho, podemos ver que temos essa base de fogo avisando que seus dados estarão diminuindo e filtrando em declínio. Considere terminar o índice na ideia da sala nas mensagens. Então vamos fazer isso. Isso é para tornar nossas consultas ainda mais desempenho. Então, vamos navegar para regras. E, vejamos, considere adicionar índice na sala I d. em mensagens. Vamos copiar isto. E essa mensagem é Vamos adicioná-la aqui assim. Agora vamos saborear e dar uma olhada se ainda podemos ter esse aviso, ok? Neste momento, o nosso conselho está claro. Não vejo nenhum aviso. Vamos novamente copiar nossas regras e colá-las. Teoh, nossas regras de banco de dados, Jason assim. Ok, então este é o fim para este vídeo. É assim que vamos gerir a nossa segurança. Agora vamos cometer nossas mudanças. Vamos em tudo para o estado do palco. E, em seguida, vamos confirmar alterações com as regras de segurança de atualização para permissão baseada em função. E isso é tudo. Muito bem, vejo-te no próximo. 132. Gestão de acesso baseado em função: Ei aí. Neste vídeo, vamos adicionar botão, a fim de ser capaz de gerenciar a permissão baseada em função. Então, quando clicamos no perfil de usuário de alguém, se estamos atualmente e estivemos fora deste grupo, somos capazes de criar este usuário e tinha sido para Não vamos voltar ao código. E vamos abrir, eu acho. Item da mensagem. Então aqui vamos fazer uma pequena modificação para informações de perfil, BT e modelo. Então vamos abri-lo. E aqui queremos exibir este botão aqui na parte inferior. Como podemos fazer isso? Bem, na verdade é fácil. Podemos passar algumas Crianças para este componente e elas serão exibidas aqui. Então aqui no perfil lateral em quatro bilhões modelo, nós também vamos d estruturar Crianças e, em seguida, essas crianças que vamos exibir no rodapé logo antes do nosso botão de fechar. Agora vamos salvá-lo. Não vamos envolver um item de mensagem. E aqui para perfil em para Betty Anne Morrow, vamos passar outro fundo para que este fundo será um elemento de bloco, e no clique vai ser algo que vai definir em alguns segundos. Além disso, ele terá cor azul e texto vai ser o próximo. Então, antes de tudo, precisamos definir quando este botão será exibido. Talvez, vamos comentar. E aqui vamos criar algumas maçãs podres e vamos primeiro movê-lo para a conversa assim. Certo, primeiro precisamos definir se podemos conceder permissão ao administrador. Então, para isso, precisamos obter nossos dados contatados. Então vamos começar é admin de usar sala atual. Deixe-me abrir o carro no contexto da sala, em seguida, deixe-me importar o gancho e do valor Begin um pico é admin. E também precisamos de outras admissões também. Então use o valor atual da sala. O valor admite assim. Em seguida, vamos envolver o nosso item de mensagem em torno de memorando, porque usamos o seletor de contexto e aqui vamos fazer o próximo. Primeiro precisamos saber se o autor da mensagem é um administrador. Então vamos criar o administrador do autor da mensagem e vamos perguntar Edmunds Inclui autor, porta do autor você eu d. Então precisamos saber se somos o autor da mensagem para que possamos criar seu autor de comestível e podemos perguntar-nos atual. Vamos importar fora do usuário atual ponto seu eu d igual autor indoor você eu d como este. E então podemos criar outro comestível que nomeará, digamos, pode conceder acesso ou pode conceder admin. E somos capazes de conceder permissão de administrador se formos adicionar Mons nós mesmos. E também, se não somos autores de mensagens então agora podemos usar todos esses objetos de valor para exibir nosso botão condicionalmente. Então, primeiro, vamos ficar pobres. Se pudermos conceder admin apenas feito, vamos exibir esta parte inferior e também para a mensagem Nós vamos colocar sua mensagem, administrador autor. Então vamos dizer “remover permissão de administrador”. Caso contrário, vamos dizer, dê ao administrador nesta sala algo assim. Ok, agora, na verdade, vamos ver o que fizemos. Deixe-me refrescar. Apenas no caso de eu abrir este perfil, Eu posso ver dar administrador nesta sala. Então, quando eu clico, nada acontece porque nós não definimos nenhuma funcionalidade. Então, vamos navegar aqui e toda a funcionalidade que vamos derramar dentro de mensagens componente, e então vamos passar essa funcionalidade para o item de mensagem. Ok, então para o item de mensagem aqui, vamos ter digamos lidar com a função admin que vamos passar que vamos ter. E para este administrador identificador. Vamos passar. Vamos dizer, autor ponto seu I d. Tudo bem, agora nós precisamos obter este identificador admin de adereços e vamos navegar para mensagens. E aqui vamos definir administrador identificador constante, e vamos otimizá-lo com antecedência com uso de chamada de volta porque nós passá-lo para baixo para elemento filho . OK, então este administrador identificador receberá o seu i d. E, em seguida, vamos primeiro definir o nosso Edmunds ref dentro do banco de dados para que possamos um objeto de banco de dados chamada . Então referência vai ser quartos do que vai ser Chat I d. Que já temos de usar perms e, em seguida, cortar avanço. Tudo bem, agora precisamos adicionar idéias de bate-papo e ouvir o que precisamos fazer. Precisamos realmente obter o nosso valor anterior, a fim de ativá-lo. Então, se clicarmos neste botão e queremos conceder a permissão, então ele será nele. Caso contrário, se esse usuário já tiver a permissão, queremos revogá-la. Então, na verdade, para fazê-lo com base de dados em tempo real, se abrirmos sua documentação, podemos ver esta seção sob leitura de dados direita salvar seções Estrin dados. Então, usando desta forma, somos capazes de obter acesso ao valor anterior e podemos atualizá-lo. E o mais importante, é transação. Isso significa que os dados não serão corrompidos. Então vamos realmente usar exatamente a mesma abordagem. Então deixe-me copiar tudo isso e o que eu vou dio eu vou chamar de esperar o que é converter esta função de corrida problema. Vamos chamar evade adicionar transação Ralf Dar masculina. Então nós recebemos nosso valor atual ou anterior, que vai ser admissão e ouvir o que vamos colocar. Vou colar o mesmo código que cooperei e aqui vou perguntar se as admissões existem . Só então executarei minha lógica. Então, se admite existir, então eu quero perguntar se admite, você eu existiria. Então quero revogar o acesso. Então eu vou definir admite que você eu iria saber. E quando definimos valor para saber para banco de dados em tempo real, ele será excluído do banco de dados porque você realmente pode armazenar nenhum valor lá. Agora, se não tivermos permissão, vamos grunhir. Então avance seu i d será definido como True. Agora vamos remover o resto do código. E no final, vamos devolver as admissões, e vai fazer a sua coisa. Certo? Chamada. Agora, precisamos notificar o usuário se revogamos ou concedemos o acesso. Então vamos colocar a porta de alerta e o que deve reportar aqui? Como podemos especificar se revogamos ou concedemos acesso a isso? Podemos criar disponível aqui que vamos renunciar. Digamos que mensagem de alerta. Então, quando revogarmos o acesso, vamos pôr alerta. Mensagem para o administrador. Permissão removida. E para ser verdade, comece uma mensagem de Miller especificada. Permissão de administração concedida, algo assim. Então vamos passar essa mensagem de alerta para informações de alerta, e eu precisamos passar esse administrador para o item da mensagem. Então, vamos lidar com o administrador. Manuseie o administrador Agora, vamos dar uma olhada. Vamos navegar de volta para o nosso aplicativo. Se eu clicar neste usuário, dar admin nesta sala. Permissão de administrador concedida. Agora tenho permissão para remover administrador. Se eu clicar nele, posso ver a permissão de administrador removida. Vamos navegar no nosso banco de dados. Vamos encontrar este quarto, que é espaço para aquele quarto. Agora. Se eu conceder acesso, você pode ver um novo valor dentro do banco de dados. E se eu remover o acesso, posso ver que ele foi removido do banco de dados. Tudo bem, acho que é tudo sobre segurança e gerenciamento baseado em funções. Vamos realmente confirmar nossas mudanças e terminar este vídeo. Mas antes de fazermos isso, vamos mover essa importação para o topo, e então vamos confirmar as alterações. Então pegue tudo, então se comprometa e vamos dizer botão adicionado para conceder ou revogar o acesso de administrador. Tudo bem, Perfeito. Vejo você na próxima. 133. Adição de uso programático com anzóis: Olá. Neste vídeo, vamos adicionar gramaticais práticos aos elementos do gráfico, e ele servirá como base para os próximos vídeos. Vamos começar. Nossa gramatical, no entanto, será gerenciada por um gancho personalizado, e nós confinamos esse gancho na Internet. Então vamos abrir o Google e vamos apenas digitar usar ganchos e, em seguida, usar o mouse. Então vamos abrir o primeiro link que permite obter o snippet de código e vamos copiar este gancho. Vou copiar toda essa função. Então eu vou voltar ao código do que dentro de ganchos personalizados no final. Vou mudar esta função, e vou exportá-la daqui. E também preciso usar rascunho para isso. Então deixe-me importar. E como posso ver, tenho essa dependência desnecessária. Mas isso não é exatamente verdade. Então vamos adicionar Sim, Lind, aviso para esta linha. E também vamos modificar este gancho um pouco em vez disso fora condicionalmente retornando a função de limpeza. Vamos levar esse retorno até o fim. Tudo bem, agora estamos prontos com o gancho. Vamos navegar para o item da mensagem e aqui vamos usar esse gancho. Então, no topo. Nós vamos criar um novo valioso, e nós vamos chamar de uso, no entanto, Gancho. Então este usa Howard Hook. Ele nos retorna uma matriz fora exatamente dois elementos onde primeiro elemento é a referência que precisamos atribuir ao elemento. Então vamos nomear-se referência e, em seguida, na verdade, o marcador valorizado que indica se este elemento está atualmente pairado ou não. Então vamos chamá-lo de auto ref e vamos passá-lo para este elemento L I. Então a referência vai ser auto ref. Agora nós podemos realmente usar este valor de barras e podemos fazer algo, mas assim por agora o que eu proponho fazer, eu só quero Teoh mudar a cor de fundo sempre que estamos pairados. Então vamos agrupamento dinâmico pobre para este elemento aliado. Então vamos roubar este psiquiatra entre parênteses e vamos usar a exaltação Rincon. E primeiro eu vou adicionar carros são um ponteiro para este elemento aliado. Então sabemos que sempre que pairarmos, algo vai acontecer. E depois vou perguntar se o nosso aliado é o Howard, deixa-me mudar para Harvard. Então eu vou mostrar o fundo preto de 0,2% cada. Caso contrário, nenhum nome de classe. Agora, se eu voltar para o código, eu posso ver que sempre que eu, no entanto, eu posso obter meu passado. Então é isso. E esse é o fim deste vídeo. Vamos cometer nossas mudanças. Vamos colocar tudo no palco ficou. Então vamos nos comprometer com o pairar gramatical pro de edição. Muito bem, vemo-nos na próxima. 134. Criando o IconControl: Likes (parte 1): Olá nestes dois vídeos vamos lidar com gostos em nossa aplicação. Neste vídeo, vamos criar um componente que vai ser um wrapper em torno de controle. Eu venho que vamos adicionar ao item da mensagem. Vamos, vamos voltar ao código e vamos primeiro definir como vamos usar este componente. Então vamos abrir a mensagem I, Tim, e vamos colocá-la logo depois de um tempo atrás. Então aqui vai ter um componente, algo como eu posso VT e controlar. E então este componente Bem, exceto nos próximos adereços. Então primeiro vamos definir se vai ser visível ou não. Por enquanto, que seja visível. Então vamos colocar eu posso nomear e por enquanto, que seja difícil para os nossos gostos. Então também, teremos dica de ferramenta que dirá algo como esta mensagem. Além disso, ele terá um manipulador no manipulador clique. Então, por enquanto, que seja uma função vazia e também terá dois adereços condicionais. Então primeiro vai ser cor e depois vai ser conteúdo de bancada. Eventualmente ele terá que Aikens fechar Aiken e, como eu conferir como eu posso queremos exibir inclinado com conteúdo. Então é por isso que vamos colocar o conteúdo em lote como um problema adicional. E por enquanto, digamos que terá cinco gostos de algo assim. Tudo bem. Agora vamos realmente criar este componente e vamos ver como ele vai ficar assim aqui Sob mensagens, Vamos criar Aiken, VT. E Controle. E vamos definir como será antes de fazermos qualquer marcação. Vamos primeiro pegar os adereços assim que temos é visível. Então também temos eu posso citar. Temos dica ferramenta que temos no Click, e temos maneira conteúdo crachá. Outros adereços que armazenaremos sob adereços. Objeto. Ok, então ele vai ser um diff com classe Nome da margem esquerda para digamos que estilo vai ser o próximo. Então vamos colocar o suporte de visibilidade, e ele vai ser visível em Lee quando é visível, definido como verdadeiro. Então, se é visível, então visível, caso contrário oculto. Está bem, está bem dentro desta definição. Precisamos derramar. Digamos que um conteúdo de lote condicional um componente condicional, e aqui está um pequeno truque. Como você pode fazer isso. Não é realmente um primitivo ou óbvio. Digamos que se aproxime. Como criar um componente de renderização condicional fora dentro de um componente. Então é o truque. Primeiro nós derramamos aqui, e você componente, digamos crachá condicional como este, ele receberá uma propriedade, que vai ser, digamos, condição onde um valor que nós queria exibir. Então aqui nós vamos derramar distintivo condicional e como um adereço, nós vamos passar condição e esta condição vai ser o nosso conteúdo do crachá. E aqui vamos perguntar se temos uma condição, então vamos para o lote de guerra com conteúdo fora de condição, que vai ser o nosso valor real. E depois vamos rapper em Children assim. Caso contrário, devolveremos crianças. Então, sim, este é o truque. E precisamos pegar crianças de nossos adereços também. Então, será algo parecido com isso, mas posso ver que algo está errado. Então, o que está acontecendo aqui? Esqueci o suporte. Tudo bem, então é isso. Agora, se tivermos muito conteúdo, este lote condicional será processado caso contrário, temos Crianças, que é todo o conteúdo que passamos dentro. Está bem, mas lá dentro vamos passar. Esporão e sussurro é o componente do nosso fato que eles usaram para algo como ponta de ferramenta . Então, por um sussurro, vamos passar. Vamos uma costeleta de colocação. Então vamos passar o Delay. Ele também tem um atraso de zero que dilly. Hide também vai ser Zito. DemaLay show vai ser também zero gatilho vai ser gritar e alto-falante. Vamos passar a dica de ferramenta e a mensagem de dica de ferramenta. Vamos passar uma propriedade culpada como esta dentro deste sussurro ou por um gatilho, vamos mostrar ícone componente normal do nosso terno. E pelo menos Aiken, botão, vamos derramar todas as colheitas que recebemos aqui, e então teremos no manipulador de cliques e vamos passar no clique que recebemos. Então vamos colocá-lo como um tamanho de círculo vai ser muito pequeno. E também eu posso em si vai ser eu posso vamos importar. E para a ICANN, vamos colocar o ícone. Posso nomear que também recebemos como uma propriedade. Agora parece pronto dentro do item de mensagem. Podemos ver que eu conveniente não está definido. Vamos importar e vamos realmente ver como ele se parece. Então, agora, se abrirmos nosso aplicativo agora, temos gostos. No entanto, não temos cor. Então, o que propus fazer aqui, vamos derramar uma coleira condicional. Então, quão vestível fazer isso? Já fizemos isso. Para que possamos servir algo assim. Podemos espalhar nosso objeto se nossa condição for verdadeira ou podemos espalhar um objeto vazio. Neste caso, não passaremos qualquer propriedade. Então vamos colocar algo como se nossa condição for verdadeira, então vamos derramar a cor do vermelho. E caso contrário, vamos colocar um objeto vazio para que ele funcione, e ele vai pensar. Agora, se eu tivesse um fresco você pode ver que eu tenho cor vermelha quando a condição é verdadeira. Caso contrário, eu tenho falso. Ok, bom. Então funciona. E a propósito, se você está se perguntando para onde ele vai, ele vai aqui para esses adereços. E esses adereços serão passados para o botão Aiken. Então, basicamente, nós dissemos cor para este botão Aiken. Ok, Então é isso para este vídeo no próximo vídeo, vamos exibir os gostos e móvel na funcionalidade. Mas, por enquanto, vamos terminar este vídeo comprometendo nossas mudanças. Leva em tudo para o estado do palco e, em seguida, obter commit. Criador, eu posso VT no componente de controle como este. Está bem, Perfeito. Vejo você na próxima. 135. Funcionalidade de letras): Hey lá nesta bolha de vídeo, adicionar funcionalidade para o botão como. Vamos lá. Vamos primeiro navegar para o banco de dados e vamos ver como vamos lidar com nossa estrutura de dados . Então, dentro de cada elemento de mensagem, vamos criar mais duas novas propriedades. First Property vai ser como Count que irá indicar o número total off curtidas nesta mensagem particular. E então teremos, digamos, digamos, gostos será uma matriz fora de valores com os IDs de usuário que gostaram desta mensagem. Mas em vez de armazenar e Ray iria usar um objeto da mesma maneira que fizemos com Rooms admite, vamos navegar para o aplicativo. E aqui vamos abrir o primeiro item da mensagem. Aqui vamos receber manipular como função e este manipulador como função. Vamos passá-lo para este próprio manipulador clique aqui. Nós vamos chamar este identificador como e para lidar, como se nós vamos passar mensagem ponto i d. Ok, agora vamos navegar para baixo em têxteis gs E aqui quando nós criamos e você mensagem, nós vamos anexar uma nova propriedade como count, e por padrão ele será definido como zero. Ok, agora vamos navegar para as mensagens para indexar os desonestos e aqui, vamos definir Const lidar como manipulador deixa o rapper entrar. Ele foi chamado de volta com antecedência. E agora vamos definir nossa lógica. Nós vamos passá-lo para o item de mensagem à luz de velas como, então ele vai receber mensagem I d. E a lógica realmente será o mesmo que com o administrador identificador porque nós vamos usar uma transação. Então vamos realmente pego ser tudo a partir daqui e vamos colocá-lo dentro lidar como, mas em vez de avanço, ref, ref, nós estamos indo para mensagem pobre, ref e mensagem Ref vai ser banco de dados Ralf do que mensagens. E então, em vez de idéia de bate-papo, vamos usar mensagem I d. Ok, então precisamos também converter esta função para em uma função de pia para transação em vez de admite que vamos receber mensagem. Então nós vamos perguntar se a mensagem existe então se a mensagem ponto gosta e mensagem Dar gosta de você , eu d off nosso usuário atual. Então vamos pegá-lo de outro objeto. Vamos usar fora do usuário atual e vamos levá-lo i d. Então, se temos, como por este usuário em particular, então vamos primeiro excluir este como e também queremos diminuir o nosso como Joan. Então vamos corrigi-lo para a mensagem Dog Gosta. Então vamos diminuir, tipo, tipo, contar por um. Então vamos garoto, meu nariz é igual a um. Uma mensagem de alerta será, como removida. Ok? Caso contrário, quando queremos derramar e você gosta, vamos colocar uma mensagem como Conan Plus é igual a um e porque podemos ter esse objeto gosta dito, você sabe, você sabe, ele pode ser inexistente dentro de bancos de dados comunidade também lidou com isso. E se tentarmos adicionar algo ao objeto não existen, teremos um erro. Então primeiro vamos perguntar se nenhuma mensagem gosta. Então, se não temos este objeto, então vamos inicializá-lo como um objeto vazio. Assim, os gostos de mensagens vão ser um objeto vazio. E só então seremos capazes de definir a mensagem. DOT gosta de seu i d igual a verdade. E, em seguida, a mensagem vai ser como ele. Está bem, Perfeito. Agora vamos dizer espere e vamos dar uma olhada. Se vamos tentar clicar nesta mensagem, teremos transação falhou, e isso é porque ele tenta atualizar como, count, propriedade inexistente para mensagens existentes. Então, o que eu propus fazer, eu quero povoar toda essa passagem é apenas para limpar um pouco o banco de dados. Então agora podemos colocar uma nova mensagem com as novas propriedades. Então vamos colocar uma nova mensagem. E agora ele tem cinco como o Conde e nós podemos realmente consertar isso. Mas por enquanto, se clicarmos nele e pudermos ver, tipo, tipo, editar se formos ao banco de dados, se abrirmos nossa mensagem, podemos ver, como contagem um e gostos contém nosso usuário i d. E se clicarmos nele mais uma vez, podemos ver que gostos é diluído e, como, contar tal para Zito. Está bem, Perfeito. Agora vamos realmente corrigir o nosso você eu Não vamos esquecer de mensagem item aqui. Precisamos passar adereços, Teoh, eu posso estar no controle. Então, primeiro de tudo, quando temos cor fora de vermelho quando nossa mensagem é apreciada, certo, Então vamos pobre é luz valiosa que vai criar aqui no topo const sua vida e como podemos definir isso. Então primeiro precisamos ver se esta mensagem tem algum tipo de gostos. Então vamos agarrar, gostos e como contar da nossa mensagem. E aqui vamos perguntar se a nossa mensagem tem gostos. Então vamos colocar as chaves de objeto fora. Estes gosta de obter matriz fora idéias do usuário e, em seguida, podemos pobres inclui, Digamos off Dar usuário atual, não é? Eu d Assim, desta forma, podemos detectar se nossa mensagem é apreciada por este usuário em particular. Certo, então vamos passar. Este é gostado de enfraquecer exibido aqui. Vamos colocá-lo dentro da condição, e então vamos colocar cor vermelha. Certo, então temos essa propriedade visível. E isso é realmente para a capacidade de resposta fora de nossas mensagens. Então, se recitarmos nossa janela, acabamos em dispositivos móveis. Então, em dispositivos móveis, não queremos ocultar nossos ícones. Queremos exibi-los sempre. Então, para isso, podemos usar consulta de mídia para detectar isso. Então, primeiro, vamos colocá-lo aqui logo abaixo usar o mouse que vamos colocar é móvel. E então vamos usar Media Query, e vamos perguntar se temos marcas com 992 pixels. Então, se temos é móvel, vamos realmente criar novo viável. Que vamos dizer pode mostrar de Aiken Então, se temos é móvel ou se o nosso elemento atual é pairado para que vamos vê-los Somente quando temos ela na mensagem Só então podemos exibir Aikens assim para é visível Nós vamos puxar pode mostrar que eu vem para no clique Nós E para o conteúdo do banco em vez de cinco vamos colocar nossa corrente como contagem Ok, bom. Agora vamos dar uma olhada Se temos onde podemos ver, temos ícone Se redimensionarmos a janela E se estamos em dispositivos móveis foram capazes de ver o Eiken. Está bem, Perfeito. Agora, se eu clicar sobre esta mensagem como, eu posso ver como contagem e, bem, ele está sendo exibido na cor off vermelho. É isto. E parece bem legal. Algum tamanho de fogo de novo? De volta à minha bílis. Posso vê-lo sempre. É isto. E acho que vamos cometer nossas mudanças. Deixe-me abrir minha pista terminal Poor obter em tudo o que poderia cometer mensagem Handle gosta Ok, Perfect. Vejo-te no próximo 136. Operação de exclusão: Ei aí. Neste vídeo, vamos lidar com delish em off chap mensagens para que escombros em outro Aiken Bt no controle para item de mensagem. Vamos lá. Vamos navegar até o item da mensagem Dodgy? Sim. E aqui ao lado de gostar, posso começar o controle. Deixe outro Aiken entre controle para excluir a mensagem e ele será visível em Lee para a mensagem. Autor. Então o autor da mensagem Onley pode fazer isso. Então vamos copiar isso e vamos condicionalmente tornar nosso próximo Aiken se tornou o controle. Então, se formos autor fora da mensagem, só então seremos capazes de ver isso. Então não precisamos de cor. Brad, precisamos que seja visível. Posso dizer que vai ser perto. Dica de ferramenta vai ser adiada Esta mensagem Nós não precisamos de conteúdo veg. E para unclip vamos adicionar alça dill que vamos receber de adereços. Certo, acho que terminamos aqui. Agora vamos dar uma olhada se eu, no entanto, eu posso ver entregue esta mensagem, ok, Muito legal. Agora não vamos envolver duas mensagens em togs de texto. E aqui vamos definir essa função. Vamos puxar o punho const dill -lo e rápido em uso chamada de volta com antecedência. Vamos também não esquecer as dependências e vamos passá-lo com antecedência para o item da mensagem. Ok, bom. Então este identificador delete recebe uma ideia de mensagem como um argumento. Então vamos pegá-lo e eu vou definir nossa lógica em primeiro lugar. Vamos perguntar se você realmente pretende entregar esta mensagem. Talvez ele só tenha clicado. Então vamos perguntar se janela confirmar, entregar esta mensagem. Então, se o usuário clicar em não, então nós vamos simplesmente retornar da disfunção. Então precisamos executar algumas operações aqui quando atualizarmos o banco de dados. Porque, como você se lembra, quando nós deliberamos mensagem aqui, nós também precisamos considerar nossa última mensagem propriedade dentro do item da sala. Então também precisamos atualizá-lo, e precisamos executar uma operação atômica. Para isso, vamos criar um objeto de atualização e, em seguida, vamos atualizar nosso banco de dados a partir da raiz, como fizemos antes. Ok, então vamos criar novas atualizações, objeto, que está vazio por enquanto. E então vamos colocar as primeiras atualizações do que as pessoas atualizam mensagens. Em seguida, vamos atualizar a mensagem. I d Annable disse que ele vai apagar a mensagem original que quando a nossa mensagem é última, queremos atualizar as informações do nosso quarto. Então primeiro precisamos detectar quando nossa mensagem é perdida. Para isso, vamos criar um novo valioso aqui, que vamos nomear é o último, Vamos colocá-lo acima atualizações. E vai ser uma comparação entre o nosso estado atual e a mensagem I D. Então vamos nos referir a mensagens. Em seguida, mensagens ponto comprimento menos um. Vamos pegar a última mensagem da nossa matriz de estado que eu d é igual a duas mensagens I d. Então, se isso for verdade, então nossas mensagens estão bem, então aqui vamos perguntar se nossa mensagem é luxúria do que para essas atualizações. Objeto. Vamos especificar salas de barra, bate-papo e depois a última mensagem é igual à próxima. Então ele vai ser o objeto anterior ao lado do nosso objeto dilatado atual. Então precisamos pegar mensagens de comprimento de ponto menos dois, o objeto anterior, certo? Então vamos espalhá-lo por toda a última mensagem. Então vamos encaminhar mensagens do que as mensagens ponto comprimento menos dois. E também precisamos especificar a mensagem i d. Como lembrar para a última mensagem. Então nós também vamos colocar mensagens, mensagens sobre comprimento menos dois pontos i d. E porque estamos tentando acessar mensagens comprimento ponto menos dois, isso pode ser agora ou este objeto não pode ser existência. Por isso, temos de verificar isso. Então podemos fazer isso simplesmente colocando aqui. Se a nossa mensagem é última e mensagens que o comprimento do pensamento é maior do que um Onley, então nós nos certificamos de que este objeto não existe. Certo, então nosso próximo caso a considerar quando tivermos apenas uma mensagem na sala de bate-papo. E quando atrasamos, queremos apagar a última mensagem dentro de informações para isso. Vamos verificar se a nossa mensagem está perdida e as mensagens são iguais a um no Lee. Então vamos puxar para a última mensagem Mel Value para entregá-lo. E no final, atualizaremos nosso banco de dados. Então vamos colocar tentar Kage. Olhe para aqui. Então nós vamos chamar, esperar banco de dados ponto rascunho atualização porta com objetos e vamos convertido para qualquer função . E também vamos especificar matriz de dependências. Então precisamos pastar idee e mensagens. E também para evitar este aviso, supressor da Colette assim. E também vamos colocar alerta aqui para notificar o usuário que excluímos a mensagem. Então a mensagem tem bean dilatado e não mensagens mensagem. E para qualquer erro, vamos colocar porta de alerta, inserir erro, mas mensagem. OK, parece bom. Agora vamos dar uma olhada. Deixe-me adicionar algumas mensagens novas. Alô? Eles estão altos. Certo, então se eu apagar a última mensagem dentro do banco de dados, posso ver que as informações do quarto estão sendo atualizadas. E agora eu tenho a última mensagem definida para lá, o que está correto. Agora, se eu fizer isso não é a última mensagem, mas uma dessas. Vamos dizer olá. Posso ver que a última mensagem dentro do item da sala não foi atualizada. Isto está correcto. Agora, se eu apagar a última mensagem, eu tenho novas mensagens. E se eu tiver apenas uma mensagem dentro do banco de dados e se eu apagar essa, ainda não tenho mensagens em ambos os lugares. OK, então isso é bom. E é assim que vamos lidar com isso. Tudo bem, vamos cometer nossas mudanças e terminar este vídeo. Vamos esquecer tudo e depois nos comprometemos. Lidar com mensagem dilatada cooperação. Muito bem, vejo-te no próximo. 137. Adição de componente de Upload - Parte 1: Santificar. Neste vídeo, vamos começar em funcionalidade para upload de arquivos. Vamos, vamos navegar para a pasta inferior e vamos abrir togs índice. Aqui vamos adicionar um novo ícone, inferior à nossa importação. Aqui à esquerda, ele abrirá o modelo Window e a partir daí faremos upload de nossos arquivos. Então vamos criar um novo arquivo dentro. Esta pasta irá nomeá-lo Anexo BT e Moto Gs. Vamos pobre Olá dentro e vamos usá-lo aqui dentro togs índice logo antes dos elementos de entrada estavam indo para exibir anexo Bt e Moto. Ok, agora vamos definir o nosso mercado. Então, aqui precisamos derramar em baixo grupo Dar porque quando usamos grupo de importação dentro, precisamos derramar no botão de grupo porta, a fim de trabalhar e olhar bem. Então, para este importante botão de grupo, vamos especificar Aiken, que vai ser apego agora precisamos para você lidar com o estado moral. Então vamos usar usar o gancho Estado Moto e vamos crescer seu aberto perto e aberto. Então, quando clicarmos neste fundo, vamos abrir nossa janela móvel. Certo, perfeito. Ao lado deste botão, vamos definir a janela mortal real. Então vamos importar modelo. E dentro de Moto, vamos especificar Mortal Heather, corpo e rodapé. Muito bem, bom para este modelo. Vamos especificar que a propriedade do show, que está aberta e também em altura, vai ser próxima para Heather. Elemento dentro, vamos derramar título Moto dentro do título Mortal que vamos exibir são arquivos pavimentados. E vamos tirar este dinheiro daqui para um rodapé modelo. Vamos pacificar um fundo para aplaudir nossos arquivos. Então vamos derramar novo elemento botão e dentro vamos derramar um Plourde. Ou talvez, digamos, enviado para conversar. Então, por enquanto, ele terá apenas uma propriedade clique. E ao lado deste fundo, vamos exibir pequeno elemento e dentro dele vai dizer que arquivos Onley menos de cinco megabytes são permitidos. E vamos alinhar este pequeno elemento pelo site certo. E também, vamos dar um pouco fora da margem superior. Está bem, vamos guardá-lo. E para o corpo, vamos especificar olá por enquanto. E vamos levar um local para ser metade. Então agora podemos ver que temos esse estranho mercado por causa dessa definição. Nós não precisamos dele. Precisamos reagir. Fragmento. Certo, mais uma vez. Agora temos fundo Quando clicamos nele, temos esse tipo de moto enviar para o Chad e onde apenas arquivos com menos de cinco megabytes são permitidos. Nosso elemento de aplaudo é carregado. O componente vai ser reativo. Então vamos procurar um plodder e vamos descer para manualmente. Então este é o tipo de componente que vamos tirar do nosso terno. Se abrirmos o snippet de código, vamos chamar P tudo isso e vamos usá-lo lá dentro. Ah, use o corpo em vez de “olá”. Vamos importar um porteiro. E aqui vamos derramar do chão igual a dois. False que ação vai ser apenas uma string vazia, porque vamos lidar com isso manualmente para evento inalterado. Vamos especificar a mudança, Heller, que irá criar. Nós não vamos usar qualquer referência porque vamos lidar com tudo manualmente. Em seguida, seremos capazes de fazer upload de vários arquivos e também menos digitar. Vamos especificar o texto da imagem. Ok, agora nós precisamos realmente tratar nosso estado para arquivos enviados. Então vamos criar um novo estado aqui que vamos nomear, arquivo, arquivo, lista e definir lista de arquivos por padrão. Vai ser uma taxa vazia e esta lista de arquivos. Precisamos passar para este componente de aplaudir. Então vamos passar lista de arquivos como estado de lista de arquivos. Agora precisamos definir isso sobre mudança, manipulador. Então vamos criar essa função aqui e este evento de mudança se tivermos nos dá lista de fogo , que é arquivado tipo. Então nós basicamente temos um array off arquivos que temos que aplaudir. Mas a partir deste raio, precisamos de um filtro de algumas coisas. Então, primeiro de tudo, precisamos permitir arquivos Onley com menos de cinco megabytes de dados. E também queremos restringir o número máximo de arquivos carregados. Digamos 25 Então primeiro precisamos definir nosso tamanho em bytes para restringi-lo. Então precisamos obter cinco megabytes em mordidas para fazer isso. Então aqui no topo, vamos criar o tamanho do arquivo Max valioso, e aqui vamos colocar Então primeiro vamos pegar 1000 que representa uma mordida. Então vamos multiplicar por 1024 para obter um megabyte em mordidas e depois multiplicado por cinco para obter cinco megabytes em mordidas. Tudo bem, então dentro deste manipulador inalterado permite pobre filtrá-lo, digamos valor ou valioso. Em seguida, vamos chamar o filtro de ponto matriz de arquivo Aqui vamos receber elemento. E para este elemento, vamos perguntar se este elemento blob arquivo ponto tamanho ele vai nos dar o tamanho fora do arquivo atual menor ou igual ao tamanho máximo do arquivo Onley. Em seguida, será adicionado ao nosso estupro filtrado. Além disso, a partir desta matriz filtrada, queremos que Onley pegue cinco elementos. Então vamos colocar fatia e a partir da fatia vamos especificar Onley 1st 5 elementos como esse. Então, logo depois disso, vamos chamar a lista de fogo e vamos derramar uma visão filtrada como essa. Certo, se dissermos que estamos agora, temos esse sinal de igual no fundo. Vamos salvar tudo. Vamos navegar de volta para o APP Vamos clicar neste botão e podemos ver que ele não está cheio com. Então vamos consertar isso rapidamente para aplaudi-la. Nós vamos especificar o nome da classe fora com 100. Agora, que poupança? E vamos dar uma olhada mais uma vez. Então, quando eu clicar neste botão, Eu vou fazer upload, Eu posso ver que ele está cheio com eu posso selecionar vários arquivos. Digamos que eu vou selecionar todos eles. Mas apenas os primeiros 5 arquivos serão selecionados. 12345 Eu posso ver que ele realmente funciona. Agora eu preciso adicionar funcionalidade para enviar para o botão de bate-papo, a fim de fazer upload de todos eles. Eu também posso gerenciá-los a partir daqui. Está bem, fixe. Então vamos criar E você, manipulador, que vai ser o nosso manipulador para isso no clique enviado para o botão de bate-papo. Então vamos criar, digamos, em um Plourde ele vai estar em uma pia, função e insight. Primeiro, vamos definir, digamos, o estado de carregamento. Ok, então vamos criar está carregando e set está carregando por padrão. Será falso. E isso está carregando. Vamos servir para este fundo. Então, para deficientes que vamos colocar está carregando para no clique. Vamos especificar um Plourde. E também vamos fazer o nosso aplaudido ou deficiente. Se pudermos fazer isso, eles desativaram. Quando é o carregamento? Está bem, Perfeito. Então, para um Plourde, faremos a próxima coisa. Vamos puxar, tentar pegar o bloco em primeiro lugar. Então sabemos que temos lista de arquivos como uma matriz fora tipos de arquivos. Isso significa que vamos aplaudir vários arquivos para o nosso banco de dados. Então, a fim de lidar com múltiplas promessas, vamos usar o ponto de promessa Tudo Mas primeiro, precisamos obter uma série de promessas para isso. Vamos criar quaisquer promessas valiosas de aplaudos e vamos mapear a nossa lista de arquivos para prometer, a fim de receber matriz de promessas. Então lista de arquivos mapa ponto vai ser arquivado. Então precisamos acessar nosso armazenamento. Então vamos colocar um depósito. Então vamos usar o objeto de armazenamento da base de fogo MISC. Então vamos puxar a referência, e vamos colocá-la. Teoh, vamos HR bater papo. Certo , assim. Agora precisamos pegar o gráfico I D. Mas é muito simples. Podemos obtê-lo usando pistas, Paramus Hook usa programas. A partir daqui vamos obter gráfico I d Reagir roteador. Vamos movê-lo para o topo. E para esta referência de armazenamento, então vamos especificar permite que um filho. Então vamos derramar um nome de arquivo e, a fim de chegar com o nome aleatório, podemos colocar simplesmente data agora e então, digamos que arquivo solha nome escuro para torná-lo mais ou menos aleatorizado. Ok, então que o seu Plourde, nós vamos despejar porta e nós podemos realmente usar este arquivo de bloco que temos de objetos de arquivo . Vai funcionar. OK, então é quase isso. Mas para este arquivo, eu quero especificar o controle de caixa. Heather, a fim de descontar dentro do nosso navegador para o porto, nós vamos especificar o segundo perímetro. Vai ser objeto off, fez um dado. Então aqui vamos especificar o controle de dinheiro e vamos fazer o próximo então vai ser público e depois marca a idade. Precisamos especificar aqui, Max, idade em segundos. Então vamos especificar três dias em segundos. Então vamos colocá-lo para fortalecer a exaltação viagem. E agora vamos fazer a nossa lógica. Então, primeiro, vamos ter uma hora em segundos, que é 3600. Então vamos multiplicar por 24 para obter um dia em segundos e depois multiplicado por três para obter três dias em segundos. Ok, bom. Logo depois disso. Na verdade, não se esqueça de retornar a partir dessa função de retorno de chamada. Então teremos a próxima coisa. Então vamos colocar um const, um Plourde instantâneos, um Plourde instantâneos que vamos chamar de “Aguarde Promessa”. Então arquivos de uma hora são carregados. Vamos receber uma matriz fora de aplaudir instantâneos. Então, como você se lembra de obter seu arquivo l quatro carregado para obter público disponível, você sabe, também é uma promessa que precisamos chamar Gedo e baixar a aura. Então, é uma promessa. Então, novamente, vamos acabar com outra área de promessas. É por isso que, novamente, precisamos mapear um novo conjunto de promessas. É por isso que vamos dizer que vai ser promessas de forma. E aqui vamos chamar “Aplaud Snapshots” Mapa de Pontos e a partir daqui vamos receber camiseta de ritmo, e esta camiseta vai nos dar a próxima. Então, vamos retornar um objeto que vai ser tipo de conteúdo snap-shore metadados tipo de conteúdo. Então teremos o nome, que vai ser arrancado. Nome do ponto de meta de dados em terra. Vai ser o nome do arquivo carregado, nome do arquivo, e então o seu próprio vai ser um peso que podemos agarrar porta de referência curto ponto get Não carregue a Europa assim. Então, esses serão nossos dados que vamos armazenar dentro do banco de dados agora para esta rua promessas que vamos criar novos valiosos, que vamos nomear arquivos. Então vamos chamar uma filha prometida de peso de promessas, e eu teria nossos arquivos que precisamos dizer para nosso banco de dados. Então, para essa cirurgia de índice interno, sim, vamos criar uma nova função que vamos gerenciar no próximo vídeo para fora. Vamos chamá-lo com antecedência. Então, a partir de adereços aqui, vamos receber uma função após um Plourde, e isso após o upload irá gerenciar arquivos carregados e disse que eles para o banco de dados. Então vamos ligar, esperar depois de um Plourde e por disfunção, vamos passar nossos arquivos dessa estrutura. Depois da chamada de volta, vamos definir o carregamento para falso. E também vamos fechar nossa janela móvel assim. E no caso de termos algum erro que vamos chamar disse está carregando. E então vamos alertar melhor a porta com mensagem de erro. Tudo bem, então este é o fim para este vídeo. Infelizmente, não podemos testá-lo ainda. Nós podemos, mas ele só vai carregar arquivos para este armazenamento. Então, no próximo vídeo, vamos continuar a trabalhar nisso. E vamos criar isso após a função de upload. Mas, quanto a agora, vamos cometer nossas mudanças e terminar o vídeo. Então, pegue tudo e então se comprometa. Anexo criado, inferior com um componente flutuante. Muito bem, vemo-nos na próxima. 138. Loja de arquivos de upload no banco de dados - Parte 2: Ei aí. Neste vídeo, vamos definir após a função de upload que mencionamos no vídeo anterior Vamos Navegar para Índice Togs Inside Bottom Folder e aqui na parte inferior direita antes de definir marcação. Vamos criar depois de um Plourde envolto em função de retorno de chamada de uso. E também, vamos especificá-lo até dependências como vazio cada Então vamos passar isso depois de um Plourde com antecedência . Teoh apego Bt e mortal. E isso após o upload recebe arquivos que precisamos derramar dentro de um debate para lembrar este anexo batendo Moto tem seu próprio estado de carregamento, e este é Onley dentro do modelo. Mas dentro em exulto. Sim, também temos o estado de carregamento desta vez para a entrada real. Então, logo antes de fazermos qualquer operação no banco de dados, vamos também chamar disse, está aplaudindo para verdadeiro dentro togs índice. Ok, então, o mesmo que para no clique enviado. Precisamos definir uma operação atômica, então vamos criar atualizações como um objeto vazio. E vamos copiar esta lógica para Digamos, quatro dados de mensagens aqui e essa tecla push agora porque temos vários arquivos que precisamos carregar e esses arquivos estão na taxa que vamos chamar arquivos para cada um olhar sobre cada arquivo dentro este direito receberá o arquivo. E para cada arquivo recebemos uma mensagem ruim e também, vamos definir dados da mensagem. Então vamos pegar essa lógica a partir de enviar Clique e colocá-lo para cada arquivo. Então, reúna a mensagem. E em vez de texto, vamos especificar arquivo e para arquivo vamos especificar objeto de arquivo que criamos dentro anexo modelo BT, que é este objeto. Ok, agora temos a mensagem I d. Temos atualizações com os dados das mensagens. Parece legal. Agora precisamos também superar se eu desejo mensagem como fazemos aqui, então dentro em algum clique é muito fácil. No entanto, agora que temos, digamos que este objeto de atualizações preenchido com esses dados, como podemos pegar a última mensagem? Embora seja realmente muito fácil, leva algum tempo para entender a lógica. Então, primeiro vamos pegar última idéia mensagem, que vai ser chaves de ponto de objeto de atualizações e, em seguida, a partir desta matriz fora, vamos dizer mensagem idéia. Vamos estourar o último elemento que será a última mensagem. Tudo bem, então vamos colocar atualizações, salas, bate-papo, bate-papo última mensagem. E em vez de dados de mensagens, vamos chamar atualizações última mensagem idee. E para a mensagem I d. Nós vamos especificar a última mensagem. bem Tudobem, e depois vamos copiar isto. Tente pegar o bloco daqui, e vamos colocá-lo bem aqui. E vamos converter essa função para qualquer coisa. Função. Assim, um banco de dados ref atualiza atualizações. Ok, Said está diminuindo Nós não precisamos em pobres e parece tudo bem agora, vamos realmente especificar matriz de dependência é com chat I D e perfil e agora estamos prontos para testá-lo. Agora, não vamos voltar para o APP. Deixe-me clicar no upload do arquivo. Vou selecionar todos esses arquivos do que abrir. Depois vou enviá-los para o Chad e posso ver mensagens vazias. No entanto, se olharmos dentro do banco de dados, eu posso ver quatro novas mensagens e nós temos arquivado, como, contagem criado em nós temos autor. E se abrirmos arquivo, podemos ter conteúdo, tipo, nome e referência euro para o nosso armazenamento. Então é isso. E funcionou mesmo. Parabéns pelo próximo vídeo. Vamos exibir todos os arquivos que carregamos. Mas, por enquanto, vamos entrar em nossas mudanças. Vamos esquecer tudo. Obter commit e, digamos, armazenar arquivos aplaudidos para D Data Maze. Muito bem, vemo-nos na próxima. 139. Exibição e download: Ei, neste vídeo, vamos exibir todos os nossos arquivos enviados. Vamos, Vamos navegar de volta para o código e vamos abrir mensagem Bytom componente o lugar onde nossos elementos são renderizados. E aqui na parte inferior em vez desta panela com apenas texto dentro, vamos colocar renderização condicional. Mas primeiro, vamos pegar não apenas texto para mensagem, mas também, digamos arquivo Agora, dentro deste diferente, somos capazes de fazer renderização condicional. Então, se temos texto dentro da nossa mensagem sobre Lee, então vamos exibir mensagem fiscal. Para se tivermos arquivo dentro da nossa mensagem, então vamos criar uma função personalizada para renderizar arquivos. Então vamos nomeá-lo, renderizar mensagem de arquivo e dentro, vamos passar o nosso arquivo, em seguida, aqui no topo para fora deste componente, vamos definir esta função, renderizar mensagem arquivada para que ele vai receber arquivo e esta função, por padrão, nos retornará apenas um link. E dentro deste link, vamos derramar o nome do ponto do arquivo de download. Se o nosso arquivo não é uma imagem e para um treff, nós vamos despejar arquivo porta Europa. Ok, bom. Agora, se o nosso arquivo é uma imagem, nós armazenamos o tipo de conteúdo dentro do banco de dados para que possamos verificar esta propriedade. Então, se o tipo de conteúdo do arquivo inclui imagem, então vamos retornar elemento dif Dentro desta def, vamos derramar uma imagem como um botão. Então, quando clicamos nele, abrimos a janela Moto. E também teremos esta vista inferior original para nos levar ao outro toque e ver o tamanho completo. Então, para este dia, se vamos especificar o nome da classe fora da altura para qualquer 20 e, em seguida, dentro, vamos criar imagem Bt em Moto e para isso no maior entre modelo, vamos passar feridas, que vão ser arquivadas. Seu nome de arquivo e também vai ser arquivado. Nome do pato. Agora precisamos criar essa imagem, beleza e Moto. Então, mensagens internas. Vamos criar nova imagem de arquivo VT no Moto Don't Yes. E como sempre, vamos servir um modelo. Mas vamos envolvê-lo em torno de fragmento reagir do que dentro. Em vez de botão, vamos colocar na porta fora do tipo de imagem. Ele faz este ato de importação como um botão, mesmo que seja uma imagem. Então, para alternativa, começar a especificar este arquivo e para propriedades, vamos especificar fonte e nome do arquivo. Então vamos fonte pobre e nome do arquivo. E como posso ver, peguei o nome do arquivo errado. Então deixe-me substituí-la por Image Bt em mortal. E deixe-me renomeá-lo com imagem Bt e Moto. Ok, então importe o tipo de imagem para fonte. Vamos especificar a fonte para no clique. Nós vamos especificar dívida aberta vai agarrar de uso estado modelo usar estado mortal assim é aberto, aberto e fechar. E também vamos especificar se vocês nomes de classe aqui, que é Max com 100 no máximo, escondam 100. E com vai ser alfa. Certo, bom é para a entrada. É isto. Agora vamos realmente definir motile. Então vamos pobre componente mortal do que Mortal Door Heather, corpo e rodapé, corpo e rodapé. Então, dentro da Heather, vamos mostrar o título mortal da porta modelo e vamos colocar o nome do arquivo dentro e vamos lidar com mortes. E isso agora dentro er comida vamos especificar apenas um link para uma torneira externa. Então vamos colocar um e um treff vai ser fonte e vamos especificar alcatrão, ficar em branco para a nova guia. E também precisamos especificar relacionamento. Sem abridor, sem rap Ferrer. Sim, assim, eu acho. E este componente não é auto-fechamento. Vamos colocar a visão original dentro e dentro da vista. O corpo do modelo ia exibir a imagem real. Então vamos colocar uma etiqueta de imagem Dan, para feridas. Vamos especificar feridas. E para a altura, digamos, 104 com , Digamos, também 100 fora vai ser deixa arquivo. Ok, agora vamos usar Isto é aberto para mostrar propriedade na altura vai ser perto e parece OK agora vamos mover esta importação para o item de mensagem superior e interna. Vamos importar este componente. Tudo bem, agora vamos dar uma olhada. Se eu atualizar o aplicativo, eu posso ver não carregar arquivo, nome, download, download, nome do arquivo e eu posso ver imagens. Então, vamos corrigir rapidamente disse Em vez desses colchetes, vamos ambos os colchetes. E agora vamos dar uma olhada para que temos fazendo carregar este arquivo. Não conheço esse arquivo. Se clicarmos nele, vamos realmente começar a baixar, e eu sempre vejo que temos imagens e quando clicamos nele. Temos essa visão original, e quando clicamos nela, chegamos ao novo toque. Está bem, parece muito bom. No entanto, em mensagens de luxúria, temos espaço vazio, então vamos corrigi-lo rapidamente. Vamos navegar até o item da sala e aqui dentro do texto da última mensagem. Vamos colocar o próximo. Então, se não temos última mensagem de texto, em seguida, vamos especificar última mensagem ponto nome do arquivo ponto e é isso. Agora vamos dar uma olhada. Temos o nome do arquivo . Muito legal. E é basicamente isso. Agora vamos terminar este vídeo e confirmar nossas mudanças. Vamos esquecer tudo. Obter commit e digamos exibir arquivos carregados de fato. Vejo você na próxima. 140. Gravação e uploads - Parte 4: Olá. Neste vídeo, adicionaremos uma opção aos registros de um usuário Plourde diretamente do navegador, para que possamos enviar mensagens de áudio para o chat. Vamos lá. Então, como eles vão lidar com isso? Bem, já que já temos o código para upload de arquivos, será relativamente fácil. Só precisamos achar uma maneira de gravar a voz do usuário. Por isso. Vamos usar reagir, Mike Library. É uma biblioteca que oferece para gravar voz do usuário e, em seguida, visualizá-lo. Mas não vamos usar essa opção de visualização. Só precisamos da gravação. Então deixe-me instalar esta biblioteca. Vou copiar este elogio do que dentro de mais terminal. Vou executá-lo. E enquanto ele está executando na pasta inferior, vamos criar novo nome vegetal arquivo. Digamos que mensagem de áudio Bt em esque cãozinho. Por agora vai ser apenas um Deve vazio. E vamos usar isso dentro de togs índice na parte inferior. Então aqui, logo após anexo, Beat e Moto Vamos usar rodeio meu disse que você é TTN e também vamos passar após o upload porque vamos enviar mensagens de áudio. Então, dentro deste componente, receberemos após o upload. E agora vamos definir bem o nosso mercado. Vai ser quase o mesmo que para apego bater Moto. Então vamos copiar o fundo do grupo de entrada a partir daqui e colado como nosso mercado. Então, vamos importar o botão de grupo de importação para unclipped. Teremos o nosso próprio manipulador e vamos também importar ícone. E por que eu posso usar meu telefone corvo? Ok, bom. Agora como somos capazes de usar isso reagir meu Kleiber Vamos para uso e exemplo. Então vamos copiar a parte de importação e colocá-la aqui no topo. Então vamos realmente usar o componente. E vamos dar uma olhada em que tipo de adereços precisamos passar. Então, primeiro temos este registro e se eu pairar sobre a propriedade, disse muito verdadeiro para começar a gravar. Então precisamos que o Estado controle. Quando quisermos começar a gravar, vamos criar uma. Então ele vai ser é gravar em. Bullen está gravando por padrão, ele será definido como false e nós vamos passar este estado para gravar propriedade que para o nome da classe , vamos colocar display none, a fim de exibir qualquer reagir Mike Element, mas para usar sua funcionalidade. Então, por uma vez, pare. Este vai ser o nosso encarregado quando tivermos a gravação e quisermos enviá-la. Então, para isso, vamos criar um manipulador Plourde. Então vamos colocar em um Plourde e com antecedência, vamos colocá-lo em uso chamada de volta. Então, por enquanto, vamos deixá-lo vazio assim e nos dados, não precisamos desse porque se rolarmos para o uso, podemos ver que quando os dados são opcionais, chamados quando uma ordem de tosse do canal está disponível não precisamos dessa. Nós não precisamos jogar cor e cor de fundo porque nós simplesmente não exibir este componente que também precisamos passar. Digo, digite esse componente para garantir que recebamos o MP 3. Ex. Então vamos passar o tipo médio e então vamos pacificar áudio MPA três. Ok, bom agora, pronto para ir. Então, primeiro, vamos definir isso no clique. Então vamos colocá-lo aqui na loja e vamos otimizá-lo com o uso frio de volta com antecedência novamente porque vamos simplesmente chamar Said está carregando e vamos reverter nosso valor Bullen aqui . Ok, bom agora para o upload, nós vamos derramar a próxima lógica. Vai ser correlativo Lee o mesmo que dentro de Attachment BT e Moto. Então, vamos precisar de referência de armazenamento para que possamos copiar esta lógica a partir daqui do que vamos colocá-lo dentro. Tente pegar o bloco aqui. Vamos receber esta promessa de aplaudir. Então precisamos convertê-lo em uma função de pia. Então verificação de referência de armazenamento, eu d. Vamos também pegar chat I d. De usar Paramus Hook do que para armazenamento. Precisamos importá-lo da base de fogo da ISC do que para a criança pelo nome do arquivo que vamos derramar. Não este nome de arquivo, mas vamos servir. Digamos que áudio do que sublinhar. E então vamos abrir dados de interpolação de cadeia de caracteres agora e, em seguida, no final, vamos colocar filha MP três do que para arquivo blob. O que precisamos especificar para o arquivo real se formos reagir? Mike on stop propriedade nos dá este registro de dados. Então, porque usamos javascript, não temos nenhum tipo. E não podemos verificar que tipo de dados recebemos aqui. Mas o que podemos fazer, podemos realmente colocar uma função diretamente aqui para obter a inteligência. Então recebemos esses dados aqui. E se eu colocar dados dar, eu posso ter blub aqui. Então este é desenvolvido tipo off objeto que podemos carregar para armazenamento firebase. Então vamos colocar o controle de dinheiro do cão de dados. Vamos deixá-lo como está agora. Precisamos também especificar o arquivo real que vamos colocar dentro do banco de dados, não dentro do armazenamento. Então vamos pegá-lo a partir daqui de anexo, bt e modelo. Vou copiar esta estrutura de objetos. Então eu vou criar um arquivo verdadeiro e então eu vou colocá-lo assim. Então instantâneo, dados de mídia. Hugh R L Ok, bom. Agora precisamos realmente chamada Onley depois de um Plourde com matriz de arquivos que queremos aplaudir porque temos apenas um. Podemos colocar apenas um array vazio e depois colocar nosso arquivo dentro. Então agora temos algum tipo de em uma taxa, certo. Então, para quaisquer erros, vamos colocar alerta Dar erro erro mensagem ponto, em seguida, para a área de dependências. Vamos passar após o upload e compartilhar I d. Vamos passar após o upload e compartilhar I d. Além disso, precisamos definir algum tipo fora de um estado de carregamento. Então vamos criar uma nova dívida viável. Vai dizer que está carregando Deixe ser dito que está aplaudindo. Então, por padrão, será falso e vamos chamar essa função antes de um Plourde e defini-lo como verdadeiro. Então, depois de aplaudir ou talvez logo antes dele, vamos dizer, está aplaudindo para falso e também no caso de qualquer arável também chamado set está aplaudindo para falso. Então agora para o grupo de entrada Bt e podemos passar desativado Onley quando está carregando. E também precisamos de alguma forma notificar o nosso utilizador quando fazemos a gravação para que ele possa compreender isso. OK, sua voz está sendo gravada para isso. Vamos pegar um nome de classe condicional. Então, se temos está gravando, então nós vamos especificar qualquer piscar de companheiro. E este é o nome da classe com a animação CSS que eu defini em uma das classes CSS . Então agora parece bem e tudo o resto parece bem. Agora podemos realmente testar a funcionalidade. Eu não iniciei, então deixe-me executar o AB agora podemos ver iniciando o servidor de desenvolvimento. Ok, vamos esperar alguns segundos até que o APP seja executado. Ok, está carregando. Agora vamos tentar gravar essa. Então, se eu apertar este botão, você pode ver que agora, aqui eu tenho Estes guia está usando sua câmera. Nós microfone este ícone. E também, se eu não tivesse permissão para usar microfone, teria me pedido isso. E agora fui notificado de que tudo bem, minha voz está gravando agora. Então, quando eu clicar neste botão mais uma vez, eu posso ver que eu tenho um novo upload de arquivo aqui. E se formos para o depósito da base de fogo do que para o Chade, podemos ficar com todos os nossos arquivos. E também mensagem de áudio. Ok, então é isso. No próximo vídeo, falaremos sobre como podemos exibir essa mensagem de áudio no primeiro que enfraquece diretamente. Ouça esta mensagem antiga dentro do navegador, mas por enquanto, vamos confirmar nossas mudanças. Deixe-me ligar, obter em tudo, então quem fez cometer e vamos especificar, opção adicionada, uma opção para gravar e um pobre arquivos de áudio. Muito bem, vemo-nos na próxima. 141. Exibição de arquivos e exclusão - Parte 5: Ei aí. Neste vídeo, vamos exibir os registros de áudio do usuário carregados. E também, vamos corrigir outro problema que surge quando começamos a lidar com o upload de arquivos. Nunca vamos voltar para o código e vamos abrir o item de mensagem o lugar onde renderizamos nosso elemento. Então, aqui nós verificamos contra o tempo do arquivo de conteúdo. Então vamos adicionar outra declaração se aqui e vamos verificar com áudios. Então vamos pedir um arquivo. O tipo de conteúdo inclui áudio. Então, se este for o caso, vamos retornar um elemento de áudio para que para esta ordem será capaz de usar controles. E também vamos pobre elemento fonte que vai ser um elemento auto fechamento. A fonte vai ser arquivada, Senhor, o seu “L “e tipo vai ser Odio MPA três. E se isso não for suportado pelo navegador, então vamos exibir seu navegador não suporta o elemento de áudio. Ok? E vamos tirar o Odeon daqui. E agora temos este ano emagrecido elementos de mídia de aviso, como um áudio deve ser deve ter uma faixa para legendas. Tudo bem, mas não temos canelas de policiais. É por isso que precisamos desativar este aviso. Vamos fazer isso. Vamos guardá-lo e vamos mover este supressor. Agora podemos ver que temos esta faixa para que possamos tocá-la. Eu posso ouvir minha voz, então ela está realmente funcionando e é isso para mensagens de áudio. Era muito simples agora sobre outros problemas que surgem quando começamos a lidar com Philip O. Quando estava doente ID a última mensagem ou uma das mensagens com arquivos do que nós só fazê-lo mensagem dentro do banco de dados. Mas os arquivos do armazenamento não estão sendo diluídos. O que quero dizer é que me deixe tentar apagar esta mensagem antiga. Então, se eu excluir aquele que eu vou para o armazenamento, eu atualizá-lo. Posso ver que é roubar deles para consertar isso. Precisamos consertar nosso casaco. Então, vamos navegar de volta para o índice togs. Mensagem interna é o lugar onde entregamos. Nossa mensagem é assim que esta é a função da aldeia tratada. Então aqui precisamos de alguma forma também executar delish arquivo em como wearable para fazer isso. Então, dentro do item de mensagem quando chamarmos, vamos encontrá-lo. Quando chamamos manipulado, excluído, passamos mensagem i D. No entanto, não sabemos se esta mensagem tem um arquivo ou é apenas uma mensagem de texto. Então vamos também arquivo pobre para esta função de exclusão identificador. Então, agora sabemos que, se houver qualquer arquivo tão dentro, como até que a tampa também receberá arquivo e logo depois de dill mensagem dentro banco de dados. Nós também podemos colocar outra tentativa, pegar bloqueio aqui, e podemos fazer a próxima coisa. Então, se tivermos arquivado, então colocaremos este bloco Tentar captura aqui dentro, e vamos primeiro pegar a referência ao arquivo dentro da história da base para que possamos chamar , digamos, arquivado. Podemos chamar de armazenamento de referência do seu inferno e se ele retornar promessa ou não saber, parece não tão referência do seu L. E então nós vamos especificar a porta do arquivo, você está fora. Então podemos simplesmente chamar arquivo ref porta dill isso Então isso definitivamente vai ser uma promessa. E no caso de qualquer outro, vamos especificar alerta sempre erro de alerta. E aqui está um momento muito importante para pegar. Imaginemos que entregamos a mensagem e isso falha. Então, se esse falhar. Isso tentará excluir a mensagem. Então, para ter certeza de que, se isso falhar, o próximo código também falhará. Precisamos retornar a partir desses bloco catch sempre que temos um erro. Então agora temos este um dissipador em uma função esperada nenhum valor de retorno. Podemos suprimir novamente o aviso sim, Lind para todo o arquivo. E agora parece bem. Então vamos primeiro excluir manualmente essa mensagem de odor que gravamos. E se eu tentar dilatar a última mensagem aqui, se eu dilatar mensagem foi apagada. E se você olhar dentro do meu banco de dados, eu tenho duas imagens. Mas se me refrescar agora, só tenho um. Então, tudo foi corrigido com sucesso. Ok, agora vamos cometer nossas mudanças. Vamos pegar tudo, então obter commits. Digamos que as mensagens de áudio exibidas e corrigir o arquivo deleite quando a mensagem está sendo entregue. Tudo bem. Perfeito. Vejo-te no próximo. 142. Feed de Chat conversa de grupo por datas: Hey lá neste vídeo mensagens de bate-papo em grupo móvel por data, então vamos ser capazes de dividir o bate-papo ajuste em mensagens relacionadas à data. Tudo bem, nunca vamos voltar ao código e vamos ver como vamos abordar isso. Então, primeiro de tudo, precisamos de algum tipo de função que agrupe nossas mensagens por datas. Então vamos criar um. Vamos abrir togs ajudantes. E aqui na parte inferior, vamos criar nova função que quem irá nomear grupo buy Ele receberá uma matriz como o primeiro argumento, e então ele vai receber a função chave de agrupamento. Vai ser uma volta fria e deixe-me explicar como vamos usar essa garota por função. Então vamos chamá-lo assim. O primeiro argumento vamos passar mensagens, matriz e, em seguida, agrupamento. A função de chave é um retorno de chamada que receberá um item fora desta matriz. Então, em nosso item de mensagem de caso, então o que retornarmos deste callback será nossa chave de agrupamento. Então, no nosso caso, é um encontro. Então vamos transformar a mensagem que eu criei em algo assim. Depois cresceu, vai nos devolver um objeto onde cada chave vai ser essa chave de agrupamento que retornamos desta chamada de volta. Então, se retornarmos data que ele vai agrupar mensagens dos EUA por data. Então vamos dizer algo como nós temos data como esta e, em seguida, vamos ter matriz off mensagens relacionadas a esta data e assim por diante, e assim um. Certo, acho que está claro. Agora vamos criar essa função. Deixe-me incomum, pai, pai, e vamos usar a matriz de pontos reduzidos para que não reduza, recebe uma chamada de volta. E segundo argumento é o valor inicial do estado inicial. Então vai ser apenas um objeto. E para o co volta primeiro argumento é acumulador vamos usar Vamos um resultado e, em seguida, o valor atual item atual apenas indo para o item ok de cada iteração vamos retornar resultado e, em seguida, vamos executar a próxima coisa Primeiro, vamos derramar chave de agrupamento valioso, e vamos chamar função chave de agrupamento e vamos passar insight item. Então, dessa forma, seremos capazes de acessar o item de mensagem dentro desta chamada de volta. Ok, bom. Agora vamos verificar contra o Vale Nulo ou vale inexistente. Então, se o resultado agrupamento propriedade chave não existe, então vamos inicializá-lo como de outra forma. Vamos receber um aviso ou um erro se tentarmos executar algo no objeto não existente . Então vamos colocar chave de agrupamento de resultados e, em seguida, vamos citá-lo como uma matriz vazia. Tudo bem, então, se isso existe, então vamos colocar o resultado de agrupamento ponto-chave empurrar item atual e é isso. Agora somos capazes de usá-lo. Vamos abrir mensagens, indexar togs, e vamos encontrar o lugar onde renderizamos mensagens. Então agora é apenas esta função de mapa por aqui. Vamos copiá-lo e dilatar. E em vez dessa função de mapa, vamos para nossas próprias mensagens de renderização funcionais personalizadas. A morte criará. Então aqui vamos const mensagens grandiosas e vai ser uma função, e dentro dela vai colocar este mapa de mensagem. Mas vamos comentar por enquanto. E aqui vamos chamar grupo por Então vamos grupos pobres de const. Então vamos chamar o grupo por. Vamos passar mensagens nosso estado do primeiro argumento e, em seguida, grupo na função chave para que ele vai receber item de mensagem e grupo de problemas por datas. Então, para especificar item criado em mas criado anúncio como lembrar, é apenas um carimbo de data/hora do banco de dados. Não é um objeto de data que podemos usar ou exibir dentro JavaScript. Então vamos convertê-lo em objeto tardio e, em seguida, estamos em conformidade com este objeto data com a cadeia de data. Tudo bem, agora temos grupos e precisamos criar elementos que vamos empurrar e exibir dentro do J 6 dentro do cão. Então vamos criar chaves de objeto, em seguida, especificar grupos e para cada método. Então, o que está acontecendo aqui que nós vamos repetir cada data, cada chave dentro de grupos objeto. Então vamos ter um encontro aqui e para todos os dias. Primeiro, vamos criar uma matriz de itens. Então deixe ser deixar itens que vamos modificar. E para estes itens, primeiro, vamos empurrar o nosso primeiro elemento. Isso vai ser um encontro. Elemento L I. Então vamos criar novo l I dentro rebelde exibido data e nome da classe vai ser margem do centro de texto não seria um e pad e também precisamos especificar chave, que vai ser data, e é único dentro deste. Os grupos organizam. Tudo bem. Agora, precisamos também enviar todas as mensagens relacionadas a essa data específica para que possamos criar novas mensagens. Todos e nós vamos usar esta função de mapa aqui. Então vamos derramar data de grupos para acessar todas as mensagens relacionadas a essa data específica que estamos iterando atualmente. Então grupo ST dot map e nós vamos mapear cada mensagem para mensagem item a partir daqui. Vamos copiá-lo e apagá-lo. Não precisamos mais dele, então vamos mapeá-lo assim, e no final, vamos simplesmente chamar itens de gato escuro e depois mensagens, certo? E na verdade é isso. E no final desta função, vamos devolver itens, e eles serão renderizados para os idiotas. Então diz que os itens nunca são resignados. Tudo bem, então vamos colocar Const, vamos salvá-lo e vamos dar uma olhada. Agora, se navegarmos, não vejo nenhuma mensagem. Deixe-me tentar uma sintaxe ligeiramente diferente. Agora, se estivermos bem frescos, podemos ter Aikens. Ok, então vamos usar esse em vez de gato. Então o que estamos fazendo aqui com espalhar todos os nossos itens em push. Então eles são tratados como argumentos separados para empurrar. Então, em vez de passar mensagens encolheradas assim, passamos assim. 12345 Muito bem, isto é o que este operador de propagação faz neste caso. Ok, então agora temos, digamos, quinta-feira, 18 de junho, se eu colocar “oi”. Agora eu tenho 19 de junho, então ele realmente funciona. E agora temos esse pequeno agrupamento. Tudo bem, então é isso. E acho que terminamos aqui. Vamos terminar o nosso vídeo. Vamos servir, pegar tudo, então você fica um pouco. E vamos especificar mensagens agrupadas por datas para efeito. Vejo-te no próximo. 143. Paginação e controle da posição de rolagem: Olá. Neste vídeo vamos lidar com a paginação dentro do chat. Agora, carregamos todas as mensagens do banco de dados e isso não é muito bom. Então, neste vídeo, vamos descobrir isso e também vamos corrigir esse problema. Quando atualizamos a página ou alternamos entre bate-papos, não vamos rolar para a parte inferior. Vamos lá. Então a questão é como você é capaz de lidar com a paginação na base de fogo? Bem, existem algumas abordagens e o mais comum é apenas você re inscrever Teoh novas mensagens de bate-papo Toda vez que carregar uma nova porção, Esta é a abordagem que tomamos. Podemos tomar outra abordagem Teoh baixar apenas mensagens antigas sobre o Senhor inicial e, em seguida, assinar novas atualizações. No entanto, essa abordagem não funcionará porque se carregarmos mensagens antigas no Lee uma vez e atualizarmos uma das mensagens, ela não será atualizada em tempo real. Então este não é o nosso caso. Queremos atualizar todas as mensagens e todas elas devem ser em tempo real. É por isso que vamos usar a primeira abordagem. Então, vamos navegar para indexar pontos gs dentro de mensagens e aqui na parte superior, vamos primeiro especificar nosso tamanho para a página. Deixe que seja o tamanho da página de 15. Agora precisamos criar ficou dentro do nosso componente que representa o nosso limite atual. Então vamos criar limite e definir limite. E, por padrão, esse estado será igual ao tamanho da página. Ok, bom. Agora vamos olhar lá dentro. Use o fato de onde buscamos nossas mensagens. Então nós temos esta mensagem, ref, que não está limitada a este uso de fato ou componente dias porque ele não usa quaisquer valores internos, que possamos movê-lo com segurança aqui para o topo. Tudo bem, Bom. Agora vamos ter que funções aqui para atrair mensagem inicial e ao Senhor mais mensagens quando clicamos no botão no topo. Então vamos criar uma nova função apenas para compartilhar a lógica. Então aqui, antes de usar o fato de criarmos uma nova função mensagens Senhor e vamos envolvê-la em uso Chamar volta com antecedência para otimizá-la. E vamos colocar essa lógica aqui dentro das mensagens do Senhor. E não apague essa assinatura. É realmente importante para cancelar a inscrição do fato do usuário também. Então agora temos esta criança RG aqui como uma dependência vamos editar. E sempre que você recarregar suas mensagens, também nos certificamos de que cancelamos a assinatura de mensagens antigas e assinamos as novas atualizações . Então aqui, logo antes de recebermos nossos novos dados, vamos chamar a mensagem ref dot off para cancelar a assinatura das atualizações anteriores. Tudo bem, agora, dentro deste fato de usuário, vamos chamar mensagens do Senhor, e vamos especificar dentro de uma matriz de dependências, e vamos remover o chat I d. porque de agora em diante, não é Partir fora deste efeito de uso. Ok, bom. Agora, e quanto ao limite? E quanto à funcionalidade Lord More? Vamos grande nova função ao lado de mensagens Senhor que vamos chamar mais baixo também permite rapper em uso chamar de volta. E o que devemos colocar lá dentro? Vamos simplesmente chamar mensagens do Senhor com o nosso limite que temos dentro do estado. Então agora precisamos especificar mensagens do Senhor e limitar como dependências e é isso. Isso é tudo por essa função. Agora, dentro mensagens senhor recebemos limite que queremos aumentar quando clicamos em Lord More. Então aqui teremos um limite. E quando tentamos novas mensagens para o nosso construtor de consultas, podemos especificar essa propriedade chamada limit to last. Então o número fora de notas para incluir nesta consulta e nós vamos especificar limite ou porque já temos limitado audível declarado vamos chamá-lo limite para não e vamos passá-lo aqui. E no caso de não termos nenhum valor em todo o legis pacificar o tamanho da página, apenas um pequeno zagueiro aqui . E toda vez que baixamos uma nova parte das mensagens, precisamos aumentar nosso limite atual. Certo? Então, quando clicarmos neste botão, nosso próximo limite será nosso limite atual mais o tamanho da página. Então aqui nós vamos derramar limite definido, e então nós vamos fazer referência anterior, anterior mais tamanho da página. Ok, agora nós precisamos definir este fundo, e nós precisamos colocar este descarregar mais manipulador para este fundo. Então aqui no fundo onde renderizamos nossa marcação, vamos colocar a próxima lógica. Então, temos que perguntar se temos mensagens e mensagens Don't Length é maior ou igual ao nosso tamanho de página Onley. Então vamos exibir um outro elemento l I dentro vamos colocar botão e dentro inferior vamos derramar mais baixo. Agora vamos adicionar alguns nomes de classe. Então, para este aliado, vamos colocar uma margem de centro fiscal no topo dois e na margem inferior também. E também para no clique, vamos especificar própria mais baixa. E também vamos colocá-lo com a cor verde, não vermelha. Eu não gosto dessa. Tudo bem, Bom. Agora vamos dar uma olhada no que fizemos. Se abrirmos nossa página agora, como eu, atualize-a mais uma vez. Podemos ver agora temos Onley 15 mensagens e se eu clicar em carregar mais, você pode ver que mais mensagens foram carregadas. Então é isso. Isto é o que está acontecendo. Então, agora, quando carregamos nossa página inicialmente, temos nossa assinatura inicial Onley tamanho de quatro páginas, que é atualmente 15. Então, quando clicamos em Lord More, isso está sendo lançado com nosso limite atual que aumentamos e ele vai ser aumentado para 30 e vamos cancelar a assinatura dessas atualizações e vamos assinar novas atualizações. Então é isso que está acontecendo em segundo plano. Tudo bem, agora, e o nosso pergaminho? Como você pode ver, ele está muito quebrado porque quando baixamos novas mensagens. Nós feijões rastejamos para o topo toda vez. Isto não é bom, por isso temos de o controlar de alguma forma. Bem, para isso, precisamos usar referência para obter o elemento real para que possamos manipular sua posse de pergaminho . Para isso, vamos criar uma nova referência aqui. E vai ser, digamos, digamos, auto ref com gancho ref usado. Ok, então vamos passar essa referência para o nosso elemento “você”. Então a referência vai ser auto-referência. E agora vamos começar a manipulá-lo. Então, em primeiro lugar, para o nosso efeito de uso inicial, quando carregamos nossa página inicialmente, queremos rolar até o fundo, certo? Então aqui nós vamos especificar nota e nós vamos referência auto ref ponto atual para obter a referência real para o nosso elemento. E aqui, logo após carregarmos nossas mensagens, podemos derramar nó rolagem superior igual a nenhuma altura de rolagem. E vai ser coisa do Lloyd. Eu sempre tive o problema com essa abordagem é que porque essas mensagens do Senhor são uma operação assíncrona e isso é síncrono, então isso pode ser executado antes que essas mensagens do Senhor tenham feito com seu pensamento, então é importante colocá-lo como qualquer pensamento operação para isso. Vamos envolvê-lo em torno de tempo definido nosso e nós vamos especificar algo como 200 milissegundos. Dessa forma, garantimos que isso esteja sendo executado em Lee quando as mensagens do Senhor são feitas e quando todos os elementos que estamos tentando exibir são exibidos na página. Tudo bem, então agora vamos dar uma olhada. Se eu atualizar a página, eu posso ver que eu não pensei, mas eu estou rolando para a parte inferior. Sim, eu posso ver isso. Um pequeno atraso de 200 milissegundos. Mas tudo bem, certo? Não há nada de errado com isso. No entanto, agora estou sendo deslocado para o fundo. Ok? Nossa próxima abordagem é realmente manter esta posição de corvo quando clicamos em Lord More. Então não estamos rabiscados até o topo. Bem, por isso dentro, Senhor, mais em primeiro lugar. Vamos novamente referenciar nossos elementos atuais. Então nota vai ser auto ref atual. Então, antes de clicar em Lord More, precisamos saber a altura anterior do nosso elemento de rolagem fora da nossa posição de rolagem. Então, quando baixamos novos elementos, obtemos a nova altura e então podemos subtrair esses valores. Então aqui vamos derramar a velha altura valiosa. E aqui vamos derramar altura de rolagem do nó. Tudo bem, então, depois das nossas mensagens, vamos ligar para o dito Tempo de novo para tornar a nossa operação assíncrona novamente. Com o tempo fora 200 milissegundos e, em seguida, dentro, vamos especificar nova altura, que vai ser nenhuma altura de rolagem. E, em seguida, vamos especificar nó rolagem superior igual a nova altura menos altura antiga. Tudo bem, agora, vamos salvá-lo. Vamos remover esse ritmo e vamos dar uma olhada. Agora estamos rolando para o fundo, e quando eu clicar em Lord More, você pode ver que esta posição de corvo é mantida. Ok, então parece muito bom. Como você está? Há mais um caso para resolver. Sempre que escrevo algo no chat, vamos dizer olá. Você pode ver que eu não estou rolando para o fundo. Então precisamos consertar isso. E, idealmente, queremos fazer algo assim. Então, se nós rabiscamos mais de 50% dentro do nosso chat e escrevemos algo, queremos rolar para o fundo. No entanto, digamos que se procurarmos algumas mensagens antigas. E se escrevermos algo ou outra pessoa digitar, não queremos rolar até o final. Para isso, precisamos também definir nossa lógica por essa razão. Aqui no topo, vamos criar uma nova função que irá nomear certeza rolar para baixo, e ele vai receber esta auto ref corrente. Então aqui vamos colocar nota, e aqui vamos colocar a próxima lógica. E também podemos especificar segundo argumento, que vai ser digamos limiar, que vai ser, digamos, 30% de por padrão. Ok, então aqui vamos calcular a porcentagem de nossa posição de rolagem, e então vamos retornar a comparação. Vamos transformar o touro em valor se a nossa percentagem que definimos aqui for maior do que o limiar que foi pacificado. Ok, então porcentagem vai ter a próxima lógica. Então, primeiro de tudo, vamos multiplicar nosso valor por 100%. Então vamos dividir esse valor por nenhum mineiro de altura de rolagem, nenhuma altura de cliente, e essa lógica nos dará a porcentagem. E como uma volta completa, vamos fornecer apenas zero. Ok? Então agora podemos usar disfunção para detectar se realmente precisamos rolar para o fundo se odiarmos o limiar. Ok, então deixe-me copiar isso e vamos às mensagens do Senhor e ouvir o que vamos fazer. Comece a pacificar Const novamente. Vamos dizer nó e então nós vamos referenciar auto Ralf corrente escura e o que ele vai fazer. Vamos colocá-lo logo depois de definir mensagens. Então vamos perguntar se devemos rolar para o fundo com nosso nó atual e vamos manter o limite como 30% Onley. Então não vamos falar de pergaminho e depois não temos altura de rolagem, está bem? E na verdade, quer saber? Podemos colocar esta nota no topo para reutilizá-la. OK, assim. Agora vamos dar uma olhada. Então deixe-me carregar mais mensagens. Deixe-me ir até o topo. E agora, quando escrevo uma nova mensagem, não sou enrolado para o fundo. No entanto, se eu rolar mais de 30% e se eu digitar caminhada, eu posso ver que eu estou sendo rolar para o fundo. Então esse é um cara. É assim que podemos lidar com a paginação. E é assim que podemos controlar nossa posição de rolagem. Ok, eu acho que não foi muito confuso porque para mim, à primeira vista, tudo bem, então vamos cometer nossas mudanças. Vamos puxar para obter tudo, obter commit e digamos que ele paginação e controle posição de rolagem. Perfeito. Vejo você na próxima. 144. Implantação na hospedagem do Firebase: Hey, Como para agora, nosso aplicativo de bate-papo tem todas as funcionalidades principais implementadas. A única coisa que está faltando é realmente notificações de tempo. A fim de implementá-lo, algumas coisas têm de ser feitas para disparar Ways Project. Vamos falar sobre isso na próxima seção e para terminar esta seção em uma boa nota, vamos implantar nosso atual Chad usando firebase hospedagem aberta Fire Base que Jason localizou na pasta de estrada para o objeto de hospedagem. Vamos adicionar pré-implantado gancho NPM executar construído Bill Script é definido no pacote Jason. Agora é tão fácil quanto digitar Firebase implantar a partir do terminal. Este comando irá implantar todas as partes do projeto que foram detectadas no firebase o Jason . Estes incluem regras de banco de dados e hospedagem. Nós também poderia implantar partes separadas executando Firebase implantar, Dash Dash apenas hospedagem após o Commander terminar, podemos ir para o host na seção dentro Firebase Dashboard. Aqui podemos encontrar um euro para acessar nosso aplicativo Bab. Haverá dois deles. Use o que você gosta mais ambos funcionarão. Firebase também mantém o controle de implantações e podemos reverter para qualquer registro de implantação no histórico de lançamentos Vamos abrir o aplicativo para ver se ele realmente funciona. - Legal. Parece bom e muito rápido. No entanto, Logan do Facebook falhará se alguém além de nós tentar entrar para corrigi-lo. Vamos ao Google e ao Time. Facebook para mortes, Clique no meu abs do que selecione aplicativo de bate-papo. Vá para configurações básicas para a política de privacidade. Euro Copy site Cuple e colado aqui do que rolar para a parte inferior. Clique em e plataforma e certifique-se de que você adicionou sua rapsódia. Clique em salvar Alterações do que ir para o painel e virou este que na parte superior para se certificar de que exibe a vida. E é isso. Muito bem, este foi o último vídeo desta secção. Na próxima seção, vamos falar sobre backend lareira personalizado com funções de nuvem. Vejo você lá. 145. Plano de projetos do Firebase: Olá. Esta seção é dedicada a notificações em tempo real e funções de nuvem. Notificações em tempo real são implementadas com mensagens em nuvem baseadas em fogo que exigem retorno personalizado . E é por isso que usamos funções de nuvem. Para que possamos continuar, precisamos atualizar nosso projeto de corrida de fogo para a planta Blaze com atualizações recentes de preços do firebase a partir de agora, chamadas funções exigem plano Blaze como o uso de alguns dos serviços de nuvem do Google que não são disponível no plano Platt Blaze livre é passado. Você vai de moto e isso não significa que devemos pagar. Todos esses serviços são dados com realmente generais. Pastor, confie em mim com as quotas dadas, você nunca vai aquecer a fronteira pagante, mas é totalmente com você. Por favor, leia mais sobre Blaze Plan na página de preços base fogo para operar para o plano Blaze. Ir para painel firebase, Clique em atualizar na parte inferior e selecione plano Blaze. Se você ainda não tem fonte de pagamento, Google irá pedir-lhe os detalhes do seu carro e depois disso atualizará o projeto para verificar qual plano? Cortando usos do projeto. Basta olhar para a parte inferior esquerda. Agora todos nos dizem que no próximo vídeo, vamos falar sobre funções de nuvem e arquiteturas de servidores menos. Vejo você lá 146. O que são sem servidor e containers?: Ei, vamos falar sobre menos servidor. Soa bem legal, certo? Para entender melhor o que é sem servidor. Vamos re sábio como o servidor normal funciona de volta é implantado servidores executando e aguardando conexões. Nada está errado aqui, mas aqui está uma pequena desvantagem. Nós não temos usuários, enquanto servidor continua a Ron e recursos de consumo. Não é muito benéfico que ele serviria a menos que um servidor implantado seja executado sob demanda. Ou é melhor dizer que o código é executado sob demanda em Lee quando é necessário. Se o acesso de ninguém na decodificação, ele não é executado. Na maioria das vezes, abordagem sem servidor é apresentada. Servidor informal Últimas funções. Cada função é implantada separadamente e tem seu próprio contexto de execução. Quando a função é implantada, ele tem seu próprio Http, seu l que é usado para investigar a função. Seu L é como um gatilho para executar o código. Não há nenhum servidor real no final. Há apenas código que é executado sob demanda. Sob o capô, toda a magia é alimentada por contêineres portuários. Um contêiner é um pacote pequeno como exaltado fora Seja o que for colocado dentro com máquinas virtuais, todo o sistema operacional é tão exaltado com contêineres em Lee. O conteúdo que é colocado dentro dele permite executar vários contêineres em um sistema operacional . Cada função implantada, com todo o seu código e dependências é colocada dentro de seu próprio contêiner que transa sob demanda quando a função é acionada. Mas os contêineres também devem ser hospedados e implantados. Samba direita Isso é controlado e gerenciado pelo provedor de nuvem. Não precisamos nos preocupar com isso. E como tudo é gerenciado para nós, também não precisamos nos preocupar com dimensionamento e manutenção. Os militantes implantados serão dimensionados automaticamente com base em chamadas de número fora. Agora sabemos que cada servidor menos função é pedaço separado de código que é executado em Lee quando realmente usado uma função não está ciente de outra como somos capazes de compartilhar algum código através de várias funções. Por exemplo, todas as funções implantadas devem acessar alguma variável compartilhada ou outra função. Depende e provedor de nuvem com fogo. código de funções da Base Cloud é compartilhado no escopo global. Quais são as desvantagens que o principal é chamado de início quando o código não é executado por um tempo, que o recipiente funções vai para o sono. Quando alguém tenta acessar o contêiner de código gira e leva algum tempo. Isso é chamado de começo a frio. Depende de múltiplos fatores. Por exemplo, qual é o tamanho da decodificação para essa função? Ou quantas dependências atesta depois que um código é executado, o contêiner permanece no estado aquecido por um tempo e aguarda por solicitações subseqüentes. Isso significa que o começo a frio não ocorrerá. Mas depois de algum tempo, quando não há pedidos, recipiente irá dormir, e da próxima vez veremos o frio. Comece com o servidor Menos. O preço é avaliado com base em chamadas de número fora e em quanto tempo cada execução cobiçada. As funções da nuvem do Firebase têm acesso livre a milhões de invocações gratuitas por mês, e isso é incrível. Agora sabemos o que está servindo menos e quais são as funções de nuvem. Espero que tenha gostado. Vejo-te no próximo. 147. Mensagem de nuvem - como tudo conectado: Olá. Vamos falar sobre mensagens na nuvem do Firebase. O que é isso exatamente? O sistema de mensagens na nuvem nos permite arejar notificações em tempo real para os usuários. Se estivermos no site, podemos receber uma notificação pop-up do nada. Se o site e o navegador estiverem fechados, podemos obter notificações nativas do sistema operacional no celular. Será uma notificação como se fosse um aplicativo móvel real sob o capô, ele usa navegadores, Boucher, FBI e a principal desvantagem de ter suporte limitado e navegadores e alguns sistemas operacionais . Está bem, deixa-me explicar o ciclo completo das mensagens da Firebase na nuvem. Portanto, cada usuário tem um token exclusivo que representa o dispositivo do usuário. Nós obtemos este token do usuário e armazená-lo dentro do banco de dados. Este token não deve estar disponível publicamente mais tarde. Fire Base usará esse token para enviar uma notificação ao dispositivo do usuário para receber notificações no dispositivo. Vamos montar um trabalhador de serviço. Como você se lembra. É um script intermediário que fica dentro do navegador. Trabalhadores colonos são frequentemente usados para realizar algumas tarefas em segundo plano. As notificações são um bom exemplo. Ele irá interceptar mensagens recebidas e usando navegadores. Bush ap I Ele irá exibir a notificação. De fato. Agora você sabe como funciona. No próximo vídeo, vamos chegar ao bode. Vejo-te isso 148. Armazenando dispositivos na base na base: Ei, neste vídeo, vamos obter token de dispositivo de usuários e armazená-lo no banco de dados. Mas antes de fazermos isso no vídeo anterior, quando implantamos nosso aplicativo, recebemos esse dinheiro de hospedagem e também modificamos fogo baseado em Jesus. Então, primeiro de tudo, vamos abrir e ser ignorados. E vamos adicionar ponto firebase fuller para obter ignore para garantir que não rastreamos esta pasta . Tudo bem, Bom. Agora vamos confirmar nossas alterações e digamos, obter commit, obter commit, Implantar o aplicativo Perfect Now Eu já abri a documentação para mensagens em nuvem do firebase, e a partir daqui precisamos obter credenciais da Web. E estes são chave de identificação voluntária do servidor de aplicativos. Então esta é a chave insípida que precisamos para configurar o Firebase Cloud doméstico em primeiro lugar. Então vamos para o painel do que vamos para abordar as configurações e, em seguida, para o sistema de mensagens na nuvem a partir daqui. Em configuração da Web, precisamos gerar novo par de chaves. Então, vamos clicar nesta parte inferior e esta é a nossa chave vazia que vamos usar. É público para que possamos compartilhá-lo. Quero dizer, não compartilhe, mas está disponível publicamente Agora vamos para a nossa aplicação. Vamos realmente executá-lo. E então vamos Oakland Firebase Doggy s em primeiro lugar. Então aqui vamos importar mensagens Firebase, e aqui na parte inferior. Vamos verificar se ele é suportado pelo navegador, para que possamos anti exportação const. Mensagens. Então vamos perguntar se Firebase morreu. As mensagens são suportadas. Então, se for, então vamos chamar o aplicativo de mensagens de ponto para obter a instância. Caso contrário, será dito que não, então, na parte inferior. Precisamos configurá-lo para usar essa chave vazia que geramos. Então vamos perguntar se temos suporte para mensagens. Então, se tivermos a instância, então vamos chamar mensagens, usar chave vazia pública. Você pode encontrar isso em sua documentação. Certo, então vamos copiar esta chave e colá-la aqui. Ok, bom. E eu preciso configurar um manipulador para nossas mensagens. Então deixe-me explicar. mensagens ou notificações estão disponíveis em dois tipos, primeiro plano e mensagens em segundo plano. Mensagens em segundo plano são aquelas mensagens que são manipuladas quando nossa guia ou navegador é fechado e mensagens em primeiro plano são aquelas que são visíveis quando estamos rolando o site, então mensagens em primeiro plano devem ser tratadas dentro do aplicativo. As mensagens em segundo plano são tratadas pelo service worker. Então aqui vamos chamar mensagens na mensagem e para conhecimento é mantê-lo como está. Dados do consulado. Então, essa assinatura, digamos, vai lidar com nossas mensagens de primeiro plano. Certo, digamos com e agora vamos decodificar para salvar o dispositivo do usuário no banco de dados. Então vamos abrir o contexto do perfil. Então este não é o lugar quando olhamos para o nosso usuário. Então aqui, precisamos gerenciá-lo. E se eu abrir novamente a documentação, eu posso ver que eu posso copiar este pedaço de código para obter token de registro atual. Então, na verdade, quer saber? Deixe-me copiar isso e vamos colar em algum lugar aqui no fundo. Mas primeiro, precisamos garantir se as mensagens existem. Então vamos verificar se as mensagens existem, que eu importei da base de fogo da MISC. Então, se esse for o caso, então eu vou acelerar esse código, e talvez você me deixe convertê-lo em um sumidouro aguarda o índice. Então deixe-me colocar um bloqueio de tentativa de captura aqui. Então eu vou colocar mensagens, pegar token. Então será Const Tokcan. Digamos que o token atual é igual a aguardar mensagens. Obter token e vamos convertido para a função de enfrentamento. Está bem, Perfeito. Então vamos verificar se o token atual existe. Vamos copiar tudo isso. Então, se esse símbolo atual existir, então vamos fazer algumas coisas. Nós não precisamos mesmo dele do que em caso de erro vamos exibir dentro do console e no nosso ocorreu. Ok, bom. Agora vamos fazer isso. Tudo isso. E aqui vamos nós. Agora precisamos armazenar esse token dentro do banco de dados. Para isso, podemos chamar longe formas de dados Dar gráfico eo lugar ou o caminho que vamos começar nossos tokens é igual a dois FC m tokens barra token I d e, em seguida, barra usuário i d. Assim, com estes abordagem, podemos facilmente consultar engasgar na parte de trás. E tudo bem, então ele vai ser FC m tokens. Então vamos para o token atual, e como uma criança, vamos derramar fora do usuário porta objeto. Eu d eu d. Desligado usuário atual. Ok. Perfeito. Agora rolando a documentação para baixo, posso ver que o token também pode ser atualizado, então também precisamos lidar com isso para isso. Vamos copiar este pedaço de código e colocá-lo ao lado deste bloco greve Hedge como este e este próprio token atualizar é uma assinatura. Então, isso significa que precisamos cancelar a assinatura dela no futuro para isso novamente. Aqui, Anti chop dentro de ti, o facto de o pobre Joe poder refrescar o meu submarino, está bem? E nós vamos derramar em token ou fresco para aquele terrível. E aqui na parte inferior, quando terminarmos, vamos verificar se brinca e atualiza no submarino, então vamos chamar essa função dois meses depois e o mesmo celular faz na função de limpeza. Ok, bom. Agora o que precisamos fazer aqui, vamos também converter-nos a qualquer coisa. Função. Então aqui, vamos colocar um canto, e na verdade, a lógica será a mesma, então podemos facilmente copiá-lo e colocá-lo aqui assim. Ok, bom. Agora estamos prontos para ir, mas como diremos ao banco de dados para o caminho que não adicionamos às regras de segurança, precisamos modificá-las ligeiramente. Então vamos para o banco de dados, então vamos para as regras. E aqui, vamos adicionar uma nova entrada. Então deixe-me copiar o status do disco assim, então eu vou substituir o status por tokens FC M. Então vamos ter uma piada. E eu D e móvel permitir Ler nunca. Porque não queremos permitir que ninguém acesse nossos tokens. E para o direito Onley o usuário, que é atualmente Sinan é capaz de armazenar seu próprio token. Certo, então vamos verificar se o novo valor do ponto de dados. Então, se o usuário i d que nós escrevemos para este token, eu t igual a dois fora de você. Eu d, ok. Bom. Agora vamos saborear e parece bom. Agora vamos para a nossa aplicação. Vamos refrescar. Certo, agora perfeito. Vamos abrir o conselho para ver se não temos avisos. Ok, nós temos o editor True. Foi toking, não foi possível registrar o service worker padrão. Ok, então isso é bom. E porque ainda não temos nenhum trabalhador de serviço, temos essa entrada. Isso é bom, mas esse erro diz que funciona. Agora vamos cometer nossas mudanças. E no próximo vídeo, vamos configurar o service worker. Então, vamos derramar, pegar em tudo e vamos verificar que tipo de outros devem ser recebidos. Declaração inesperada do Conselho. Certo, isso é bom. Vamos nos comprometer. E digamos editar mensagens firebase e armazenar token de usuário estrangulamento no banco de dados. Perfeito. Vejo-te no próximo 149. Adição de trabalhador de serviços: Ei aí. Neste vídeo, continuaremos configurando mensagens na nuvem do firebase e configuraremos um service worker. Então eu já navegei até a documentação do firebase e, em seguida, escolhi mensagens recebidas. Então, nesta seção, eu posso ler e você pode ler mais sobre mensagens de primeiro plano e segundo plano, mas estamos interessados no arquivo do service worker. Então não vamos esquecer o nosso código e a primeira coisa que vamos fazer, mas realmente pegou as regras que criamos no vídeo anterior com tokens FC M. Então vamos copiar tudo isso, em seguida, ir para banco de dados tolos Jason e Colar todos eles aqui agora sobre service worker. Então, como você pode ver, este é realmente o código do service worker. Vamos chamar de ser isso. E dentro da pasta Pública, vamos criar novo arquivo firebase serviço de mensagens Worker doggy s. Portanto, ele deve corresponder a este nome de arquivo. É muito importante porque este é o nome que será reconhecido pela base de fogo como decadência . Agora vamos colar tudo o que temos aqui e podemos realmente fazê-lo. Todos esses comentários assim, então não precisamos da mensagem. Incrível. E também, vamos desativar es fiapos para todo o arquivo. Ok, bom. Agora, para esses conflitos aqui, precisamos inicializar nosso conflito que inicializamos dentro de nossa aplicação. Então vamos abrir a base de fogo Dodgy. Sim. E vamos apenas copiar este objeto e colocá-lo aqui para que ele irá inicializar firebase sdk dentro do service worker. E também devemos garantir que a versão que importamos aqui deve corresponder à nossa versão sdk dentro do pacote Jason. Então vamos abri-lo. E aqui temos 7.15 agora vamos esperar no trabalhador de serviço, ele tem 7.15. Tudo bem. Agora vamos salvá-lo. E eu já cuido do laboratório. Agora vamos voltar para o APP. Deixe-me atualizá-lo agora, como podem ver dentro do conselho, não tenho avisos, então vamos navegar até o nosso banco de dados. E como você pode ver agora eu tenho tokens FC m aqui. Se eu abri-lo, eu tenho este bastante longo usuário I d token e que eu tenho meu usuário i d e isso é realmente ele antes de nós confirmar nossas alterações porque nós usamos um novo service worker com mensagens em nuvem firebase dentro. Na verdade, não precisamos de service worker criando app reagir. Por isso, aquilo que propus fazer no futuro, vamos precisar disso. host local é valioso? Então vamos copiá-lo daqui e colocá-lo dentro de ajudantes como este e vamos exportar a partir daqui . Agora vamos salvá-lo E vamos excluir serviço, arquivo de trabalho e dentro após GS ou dentro de togs índice. Vamos excluir esses comentários. Não precisamos mais deles, e agora podemos fazer nossas mudanças. Então, novamente, vamos embarcar em tudo e depois nos comprometer. E digamos que, trabalhador de serviço que disse Perfeito, te vejo no próximo. 150. Configurar funções de nuvem e Node: Ei aí. Neste vídeo, vamos configurar funções de nuvem dentro de nosso projeto firebase. Vamos lá. Vamos voltar para o código V. Vamos abrir o terminal. E aqui só precisamos digitar base de fogo. Você precisa de funções. Em seguida, ele irá nos fazer algumas perguntas. Vamos bater. Sim. Então vamos escolher Javascript. Então quatro anos Lind, vamos selecionar. Sim, e vamos instalar todas as dependências. Ok, bom. Se olharmos dentro das funções, alguns arquivos foram criados para nós. Sim, Lynn RC com conflito já pré-definido. Não vamos mortificá-lo. Então temos que ignorar Index Dodgy s e empacotado Jason, Então índice de pontos gs em funções de nuvem é um ponto de entrada de togs índice. Arquivo RealAge para exportar funções de nuvem separadas que serão implantadas separadamente. Ok, dentro da bicicleta. É o Jason. Aqui podemos encontrar algumas dependências. Então sim, Lind e também firebase admin e funções. Estes dois pacotes nos permitem acessar base de fogo a partir de backend e também podemos encontrar alguns scripts. Definir aqui servir para realmente Ron funções emulador no ambiente local do que temos algo chamado Shell e é shell firebase para realmente testar nossas funções e também seguida, temos logs e outras coisas, como implantar e iniciar para iniciar script de início . Já que vamos testar nossas funções localmente, propus ao Ron servir em vez da Shell. Então vamos colocar isso para servir e vamos salvar nosso arquivo. E também porque vamos acessar nosso banco de dados localmente e pela base de fogo. Ele é reconhecido como um ambiente não confiável. Precisamos fornecer algum tipo de autenticação ou credencial, a fim de fazê-lo funcionar. Então, para isso, precisamos navegar de volta ao nosso painel. Então precisamos ir para as configurações do projeto e ir para as contas de serviço a partir daqui. Não precisamos baixar a nova chave privada. Então vamos criar um. Vai dar-nos um ficheiro do Jason. Vamos abri-lo e copiamos o conteúdo. Vamos voltar para o código. E aqui dentro funções, vamos criar nova conta de serviço de arquivo, faz Jason e vamos colocar tudo o que temos Koppett. Agora, por favor, certifique-se de adicionar este arquivo para ser ignorado. Isto é muito importante. Então, aqui nós adicionamos conta de serviço que Jason, então este arquivo não deve estar disponível publicamente. Isto é apenas para nós, para o desenvolvimento local. Ok, bom. Agora, se abrirmos novamente as contas de serviço aqui podemos encontrar um pequeno trecho de código, então vamos copiá-lo e vamos abrir o ponto de índice Js. Então aqui temos funções no topo e funções firebase. Vamos colocá-lo assim. E vamos também pegar o administrador e substituir VARS com constante Good. Agora precisamos especificar um caminho de conta de serviço que é este e, em seguida, colocá-lo dentro, admin initialize em quando usamos funções de nuvem. Antes que possamos fazer qualquer coisa, precisamos inicializar firebase admin como deteriorado e para o desenvolvimento local, precisamos inicializá-lo assim, a fim de acessar os dados reais, a fim de acessar o banco de dados riel . É basicamente isso. No entanto, há uma coisa importante para as funções de nuvem. Se abrirmos o pacote do Jason aqui, confinamos os motores. Nó oito especificar. A coisa é que as funções de nuvem do firebase são suportadas no Lee dois sem versões GS, oito ou 10 e recentemente eles deixaram de suportar para a versão do nó oito completamente. Agora as funções da nuvem do firebase estão basicamente disponíveis sem versão SIG. Ted, isso pode ser um pequeno problema agora. Nós não usamos Js versão 12 e precisamos de alguma forma gerenciar nossas funções de nuvem com nota versão 10. Para isso, precisamos alternar entre diferentes versões conhecidas Jess. Para isso, precisamos não baixar software adicional, que é chamado de No Version manager. Este é um software que nos permite alternar entre diferentes versões desligadas. Nenhum GS em um comando. Certo, vamos ao Google. E, em seguida, vamos apenas digitar e VM que Vamos para anotar o gerenciador de versão no get hop. E este repositório está em lee para usuários Linux e Mac OS. Siga este tutorial e instale e VM em sua máquina. Se você vem de janelas para baixo, role para baixo para duas janelas parte E aqui nós confinamos inveja M para janelas e, em seguida, clique em download. Agora você vai acabar nesta página, em seguida, clique em N V M. Configurar arquivo zip e, em seguida, instalar inveja M. Ok, Depois de ter inveja M instalado em sua máquina, vá para o seu terminal e, em seguida, basta chamar inveja M versão ou inveja em. Versão Dash. Está bem. E a versão VM depois disso, a fim de instalar No, apenas a versão 10. Deixe-me executar o meu comando e a lista M. Ele irá listar todas as minhas versões sem GS instaladas localmente. Então, para funções de nuvem, precisamos de alguns fora da 10ª versão. Então vamos chamar inveja M instalar e, em seguida, 10.20 ponto um. Após essa versão de nota, Manager irá instalar e principalmente tudo para você. Você não precisa se preocupar com nada, então para alternar entre diferentes versões desativadas. Sem GS enfraquecer, simplesmente digite e VM usada. Digamos 8 16 para. E agora estou usando esta versão fora da nota. E se eu digitar e VM usar 10.20 ponto um agora estou usando esta versão. É isto. É assim que podemos gerenciar diferentes versões fora. Não Gs, certifique-se de que você tem este instalado porque caso contrário, se você não tiver nenhuma versão 10 instalada localmente, não poderemos executar suas funções localmente. Tudo bem, agora, para terminar este vídeo, vamos cometer nossas mudanças. Então vamos esquecer tudo. Em seguida, cometa e digamos, configure as funções da nuvem com inveja. M perfeito. Vejo-te no próximo 151. Fluxo de notificações no nosso aplicativo: Olá Neste vídeo, quero explicar rapidamente o fluxo para enviar uma notificação. Em primeiro lugar, nos dados, por favor. Para cada sala, haverá um outro campo chamado usuários do FC M. Será nas idéias do usuário Rafe que receberão notificações na parte de trás. E vamos criar uma função de nuvem que vai chamar a partir do nosso aplicativo de bate-papo como uma definição de administrador dois, juntamente com o pedido que enviaremos de poderoso nome e mensagem de notificação. Em seguida, usando Crew my D, vamos obter IDs de usuário que recebem notificações usando suas idéias. Vamos consultar seus tokens de dispositivo e, em seguida, enviar uma notificação usando os tokens do antes de começar . Eu só quero salientar que existem três tipos diferentes de funções de nuvem. funções ingénuas a pedido e gatilhos a pedido têm o seu próprio euro enviar em um pedido. A utilização do euro é a única forma de aceder à função. Chamar um intestino Funções também têm o seu próprio neural, mas no cliente firebase como decadência, o que usamos no navegador, existe um método especial para chamar este tipo de função pelo seu nome, não por euro e também chamável funções automaticamente analisar e validar tokens JWT do usuário. Firebase usa tokens JWT para autorizar usuários, e nós não lidamos com eles diretamente. As funções de gatilho não têm seu próprio neural, e eles respondem em Lee dois eventos de documentos de banco de dados diferentes, como criação própria na atualização e Illit propriedade. Poderíamos especificar que cada vez que um documento é criado nesse caminho, esta função de nuvem será executado sempre. No nosso caso, só precisamos de um tipo de funções crédulas, fáceis de acessar e usuário fora de seu protesto para nós. Agora, você tem uma idéia melhor do que vamos fazer. Vejo-te no próximo. 152. Criando função de nuvem FCM: Santificar. Neste vídeo, vamos criar nossa própria função lavada para enviar mensagens de notificação. Vamos lá. Primeiro de tudo, vamos abrir esses códigos do que vamos para funções, togs índice e, vamos incomum, esta função de nuvem de dobra que já bastante encontrar para nós. Vamos salvar este arquivo. Em seguida, vamos abrir o terminal e navegar para a pasta Funções em pacotes e temos NPM executar script de início. Então vamos executá-lo e vamos dar uma olhada no que vai acontecer? Então, em primeiro lugar, ele não vai diminuir todos os emuladores necessários para diferentes serviços fora da lareira, como AM um líder para funções. Isso é bom. Depois disso, você verá esse tipo de mensagem, e ele vai dizer que a primeira função http é inicializada e disponível nestes Ural e também temos este host local para 1000 funções. Então vamos copiar essa. Vamos para o navegador e vamos abrir este campo para verificar o que vai acontecer. Isso é como um painel onde controlamos quais serviços desenvolvemos localmente. Então agora temos apenas funções. Sou um líder e está disponível nesses portos, e se formos para registros, podemos ver isso. Agora temos uma função http inicializada para que possamos copiar este ano. E então podemos acessar essa função. E pela resposta, podemos ver olá da base de fogo. Isto é o que temos dentro desta função. A Defiant. Então é isso. Isso é o que nossa nuvem funciona. Mas agora, vamos parar o emulador. Nós não precisamos dele. E vamos também excluir esse tipo de função porque este é um duas vezes um e nós não precisamos dele. Mas antes de fazermos isso, eu só quero salientar que cada função que exportou do oci indexado sim, é tratada como uma função. Então, o que ele fará dentro das funções. Vamos criar uma nova pasta chamada “Ser C Inside”. Nós vamos derramar novo arquivo FC M cãozinho s Daqui, vamos exportar nossa função e, em seguida, vamos re-exportá-lo a partir daqui. Ok, então vamos mantê-lo como está. Talvez nomeemos essa função com antecedência. Digamos que mande o FC M. E, por enquanto, vamos comentar. Ok. Bom. Agora dentro do FC M. Vamos importar funções e administrador. E daqui, vamos exportar nossa primeira função. Vai nomeá-lo. Exportações exporta e fc M. Então precisamos chamar funções. Então precisamos derramar https, e então precisamos colocar em serviço. Então esta função que vem por padrão foi no tipo de solicitação de função que eles querem, mas vamos criar vai estar em chamada. Ok, então isso na função fria recebe dois argumentos. Então, se no entanto, podemos ver dados e contatos, Então dados são esses dados que passamos junto com solicitação e podemos acessá-lo dentro do contexto contém algumas informações de contexto, como informações do usuário e usuário JWT Token. Vá. Agora. Desde que exportamos esta função do arquivo do FC M Dodgy s, podemos importar dentro togs índice. Então aqui podemos digitar Const. Deixe-me digitar f igual exigir do que vamos referenciar pasta fonte e, em seguida, f c M g s. Então, a partir da disfunção, nós exporta e FC M Agora precisamos destruí-lo. E, em seguida, a partir deste índice togs, nós vamos voltar a exportá-lo assim. Então as exportações areia FC M vai ser enviado FC M função que obtemos a partir do arquivo FC M. Tudo bem. E temos este aviso dizendo esperado uma linha vazia. Ok, deixe-me colocar assim. Agora precisamos escrever nossa função. Ok, então primeiro de tudo, precisamos verificar se nosso usuário está presente. Se a pessoa que tenta acessar esta função é realmente autenticada, já temos usuário analisado e validado por este tipo de função, que é culpável. Agora precisamos apenas verificar se o usuário é realmente analisado. Então, se o usuário não é analisado, isso significa que o usuário não está presente. Ok, para isso podemos criar uma função auxiliar aqui que vamos nomear check se off check. Se autenticado dentro desta função, vamos passar o contexto, e então vamos chamá-lo de nossa função assim. Verifique se desligou e depois passaremos o contexto. E a partir deste cheque se desligado, faremos o próximo. Se o ponto de contexto auth ele tem fora do objeto dentro. Então, se eu derramar contexto e, em seguida, dar aqui confinado fora. Então, se este contexto não está desligado é indefinido. Então, se não temos nenhum objeto fora, então vamos lançar novas funções. Dar Https. Erro http Então este é Paschall. Digamos que sintaxe que dará um erro para recusar nossa razão será autenticado e mensagem vai ser. Você tem que estar conectado. Ok, bom. Aqui estamos feitos. Nosso próximo passo é acessar os dados que obtemos a partir do pedido. Ele está disponível sob este objeto de dados. Por aqui. Já está analisado para nós. Então, a partir deste objeto, podemos destruir os próximos valores, vamos lixar o Chad. Eu d, em seguida, título fora da sala ou deixa o título da mensagem. E então também, vamos enviar mensagem. Ok, bom. Agora precisamos de obter os dados da sala usando esta cadeira. Ok, apartir daqui , vamos ter uma foto do quarto. Ok, apartir daqui , partir daqui , E agora precisamos acessar. Nosso banco de dados pode ser acessado a partir do ambiente de servidor usando firebase admin como decayed. Então aqui no topo, vamos colocar um novo banco de dados viável, e então vamos chamar o banco de dados administrativo. Usando banco de dados do ambiente de servidor é muito semelhante à forma como acessá-lo de recusado. Ok, então agora podemos chamar o banco de dados, então nós colocamos áspero, e agora nós precisamos acessar de dados. Então nós passamos por salas que sala de corte I D. que vai ser chat, i d. No nosso caso, ele retorna a promessa. É por isso que podemos guardar aqui. E também vamos colocar uma pia para torná-la válida. Então, depois de termos referência, nós chamamos uma vez e, em seguida, nós mau valor. Agora temos o instantâneo do quarto, então podemos fazer a verificação simples se o quarto Snap Shore existe. Então, se não existir, então vamos devolver False. Ok. A partir desta função, ele irá enviar apenas solicitação falsa de volta para o cliente. Quando vamos chamar essa função, então precisamos obter dados da sala para obter um ID de usuário. Então, para isso, vamos os dados do tribunal e, em seguida, vamos gravar a partir do valor da porta instantânea. Agora, precisamos verificar se nosso usuário atual é um administrador. Então nós podemos realmente enviar a mensagem porque esta função pode ser chamada por algum usuário dentro do Chad. Mas este usuário não é um administrador e, portanto, este usuário não é capaz de enviar a mensagem. Ok para isso, precisamos verificar contra o usuário admite então primeiro, Como você se lembra, todos os nossos uma corrida nos trabalhos são armazenados são objetos, então precisamos transformá-los em matrizes javascript normais para que Inside ajudantes. Já temos disfunção transformada em matriz. Vamos copiá-lo daqui e colocá-lo aqui no fundo. Agora podemos criar uma função auxiliar para verificar se o usuário realmente pode enviar a mensagem. Podemos criar uma nova função na parte inferior novamente, e vamos nomeá-la. Verifique se permitido. E novamente ele receberá contexto. E também receberá o chat admite. Ok. E aqui vamos fazer quase a mesma verificação. Então, se não, digamos Chad, adicionar Mons cão inclui contexto off, e então você i d. Então, se o usuário que está tentando acessar esta função de nuvem está na lista fora de Chad Adnan. Então, se este não for o caso, então novamente nós vamos enviar exatamente a mesma mensagem para cá. E talvez digamos acesso restrito. Tudo bem, Bom. Agora podemos chamar essa função aqui. Verifique se permitido, vamos passar contexto dentro, juntamente com transformar para matriz dados sala admite. Certo, perfeito. Nosso próximo passo é obter ideias reais de usuários que receberão notificações. Por isso. Vamos colocar novos e valiosos usuários do FC M. E novamente, vamos chamar transformar em matriz, e vamos colocar dados de sala usuários FC M. Ok, agora vamos obter todos os tokens de usuário. Por isso. Propus criar novamente uma função auxiliar que chamaremos de obter tokens de usuário. Então vamos rolar para o fundo. E aqui vamos criar uma nova função, obter tokens de usuário para que ele receberá o usuário I D. E ele receberá todos os tokens de usuário. Então vamos chamar nossas formas de dados, e receberemos tokens de usuário. Snapshot. Ok, então vai ser uma função inocente e a lógica será a próxima. Então vamos chamar o árbitro do banco de dados. Então vamos fazer referência aos tokens FC M. Então vamos ordenar por valor, e vamos colocar igual ao usuário I d. e, em seguida, para obter tokens antigos, vamos chamar valor uma vez. Está bem, Perfeito. E não se esqueça de esperar no início. Agora temos camisa de encaixe de token de usuário. Então, se não temos tokens de usuário, snap short tem Crianças. Então, aqui nós verificamos se realmente este usuário em particular tem algum token. Se este usuário não tiver nenhum Filhos, isso significa que este usuário não tem nenhum token. Então podemos simplesmente devolver um vazio, Eric. Então, se o usuário tem tokens, então chamamos chaves de ponto de objeto e, em seguida, token de usuário valor de ponto instantâneo. Porque, como você se lembra, nós armazenamos nosso aumento de A nos caminhos-de-ferro como objetos. E ao chamar este objeto de chaves, obtemos os tokens de usuário reais. Ok, bom. Agora podemos chamar isso de obter tokens de usuário da nossa função de nuvem e para o pai, porque precisamos obter tokens de usuário para vários usuários precisamos usar Promise que tudo para torná-lo o mais otimizado possível. Ok para isso Aqui, vamos criar um novo usuário valioso. Fichas, promessas. E o que faremos. Vamos mapear todos os usuários do FC M. Vamos mapeá-lo. Então, cada usuário i d vai ser mapeado para obter tokens de usuário prometidos. E dentro dele vai ter este usuário eu d. Ok, bom. Agora vamos receber o nosso resultado. Ou digamos que vamos receber o resultado de tokens de usuário e vamos chamar, aguardar promessa. Nem todos os tokens de usuário promete, mas a coisa é que a promessa de que todos nos retorna uma matriz fora de resultados como esse e nossos tokens de usuário promete, então cada promessa de tokens de usuário nos retorna uma matriz fora de tokens de usuário. Então, desta forma, vamos acabar com matriz aninhada assim. Então, para o primeiro usuário, teremos esses tokens. Então, por segundo, podemos obter estes e assim um e assim por diante. Então, para evitar isso, precisamos achatar nosso Eric. Para isso, podemos chamar ponto reduzir método disponível em uma corrida e achatar a área. Ok. Para isso, vamos chamar o resultado de tokens de usuário, em seguida, reduzido, para que ele receberá uma função de retorno de chamada. E o segundo argumento é o valor inicial. Então o poço inicial vai ser um array vazio. E este uso de doutrina primeiro é o valor acumulador, que vai ser, digamos, acumulado, Filkins. E o segundo será o valor atual, que é tokens de usuário. Portanto, esta função será executada para cada token de usuário para cada elemento. OK, e aqui vamos simplesmente fundir. Estes dois apagam usando o operador de propagação. Então vamos chamar tokens de acumulador, mais tokens de usuário. Assim, desta forma, vamos acabar com um plano e matriz onde cada token como é um valor normal . Está bem, vai agora. Vamos seguir em frente, então vamos verificar se o comprimento do ponto tokens é igual a zero que retornará a partir desta função porque não temos nenhum token para enviar dois. E como a questão é que temos fichas, como somos capazes de enviar nossas mensagens para que possamos navegar para fogo por sua documentação. Então este é o que eu tenho de vídeos anteriores. Mas se eu ir para o ambiente de servidor à esquerda e, em seguida, criar solicitações enviadas aqui, você pode encontrar várias maneiras. Como posso enviar uma mensagem para especificar o dispositivo? No entanto, precisamos apenas de um que é enviado mensagens para vários dispositivos porque temos vários tokens e temos uma mensagem para enviar. Então deixe-me copiar a mensagem, na verdade, e eu vou colocá-la aqui, e eu vou chamá-la de mensagem F C M. Então eu estava dados não vai se parecer com isso porque cada mensagem também pode ter estrutura diferente . Ele pode ter este tipo de objeto com tópico de dados e tokens têm sempre Este é Onley para notificações personalizadas. Não precisamos de nada personalizado. Precisamos de uma notificação normal para isso. Precisamos modificar um pouco este objeto. Então, em vez de dados, vamos objeto de notificação ruim dentro. E esse objeto de notificação tem duas chaves, que é título e também corpo, que é a mensagem de notificação real. Então, para o corpo, vamos ver mensagem pacificar que recebemos do objeto de dados dentro desta função de nuvem. Então vamos colocar a mensagem. E para o título, podemos derramar o nosso título personalizado, que vai ser intitulado que enviamos com pedidos e também nome do quarto. Ok, então vamos ser o título de quarto pobre. Então vamos colocar o título e, em seguida, do nome da porta de dados. Então, desta forma, teremos título e do nome ao lado dele. Mas vamos colocar talvez o nome do quarto em atenuações dos pais para que pareça mais estético. Está bem, vai lá. Agora vamos dar uma olhada em como somos capazes de enviar isso. Podemos usar mensagens ponto admin feito, disse multicast, e depois mensagem. Ok, bom. Então precisamos usar mensagens de ponto admin. Vamos criar disponível aqui chamado Messaging on. Vamos ligar para as mensagens do administrador. Ok. Perfeito. Agora podemos copiar esse código. Deixe-me copiar apenas a primeira linha porque não vamos usar as promessas no Texas. Vamos usar um pensar longe. Então deixe-me ligar para mensagens administrativas const. Eu vou substituí-lo por mensagens, então enviar multi cast e nós vamos enviar mensagem FC M, e nós vamos colocá-lo em um verdadeiro, que chamado Batch responde, e então vamos esperar este comando. Ok, bom. Agora, o problema é que os tokens podem ser inválidos ou os tokens podem expirar porque, como você se lembra, no token de recusa pode ser atualizado. Assim, quando o token é atualizado, o token anterior não é mais válido. Então este é o caso quando falhamos tokens. Então, podemos realmente usar esse trecho de código para detectar quais tokens estão falhando, e então podemos entregá-los do banco de dados. Deixe-me copiar este trecho de código, e eu posso chamá-lo assim, então teremos muitas respostas e verificamos se muito responde. Contagem de falhas é maior que zero do que para cada resposta scones amanteigados. Analisamos as respostas e verificamos se as nossas respostas não foram bem-sucedidas. Então este é o caso. Todos os tokens com falha foram enviados para essa taxa de tokens com falha. No entanto, queremos fazer alguma coisa com eles. Certo? Queremos limpar nosso banco de dados também. Para isso, vamos puxar esses tokens falhados aqui para o topo, e faremos a próxima coisa. Então, atualizaremos nossos tokens falhados. Com este empurrão dentro, removeremos esta fechadura do cônsul. E agora que todos nós temos tokens falhados, nós podemos realmente chamar nossos dados maneiras até que todos esses tokens aqui no final, nós vamos criar um novo array fora de promessas que vamos executar com o ponto de promessa tudo novamente porque nós podemos até que vários tokens do banco de dados. Para isso, podemos criar remover promessas valiosas. E vamos mapear cada token falhado para prometer assim fichas falhadas mapa ponto. Então teremos token, e vamos chamar o banco de dados Dot Rascunho. Então vamos chamar o FC M Jokinen do que Tokcan e depois a porta foi removida. Está bem, Perfeito. Assim, desta forma, vamos acabar com um raio fora, remover promessas, e no final fora de nossa função de nuvem, podemos chamar retorno promessa pensamento tudo e vamos derramá-lo de promessas e, em seguida, no caso fora de qualquer erro que podemos usar realmente ponto pegar Syntex aqui em vez de um pensar esperar. Porque esta é a nossa última operação e parece mais legível neste caso. Então, no caso de qualquer outro, vamos retornar mensagem de ponto de erro. Está bem, Perfeito. Então é isso. Esta é a nossa função, e é assim que vamos gerenciá-la. Acho que é isso para este vídeo. E no próximo vídeo, vamos começar a atualizar nosso cliente. Vamos testar essa função e o que eu propus fazer. Como você pode ver nos arquivos. Aqui, temos você I d. Bach. Vamos adicionar este arquivo para ser ignorado. Você eu ou talvez vamos adicionar todos os arquivos de aparência para ser ignorado. Não precisamos deles. Está bem, fixe. E temos este aviso dizendo que se espera retornar ao valor. Ok, talvez nós possamos realmente atualizar o nosso fiapo sim para que possamos colocar um retorno consistente e consistente seria zero. Ok. E parece que já temos um algures aqui. Vamos colocar em zero. E vamos entregá-lo aqui para evitar este tipo de aviso dentro do nosso arquivo e também para o Islã , Darcy, porque temos vários arquivos de criação dentro do nosso projeto. Um na pasta raiz e outro aqui. Também queremos ter certeza de que adicionamos opção rota é igual a dois. Verdadeiro. Então agora ele é reconhecido por decodificação. Certo, perfeito. Então, por enquanto, estamos acabados. Vamos cometer nossas mudanças. Então nunca vamos voltar para a pasta raiz. Em seguida, vamos chamar, obter tudo e, em seguida, obter commit e digamos editar função de nuvem para enviar mensagens FC M. obter tudo e, em seguida, obter commit e digamos editar função de nuvem para enviar mensagens FC M. Perfeito. Vejo você na próxima. 153. Correção de função na nuvem: Ei aí. No vídeo anterior, quando criamos enviou função FC M Cloud, Eu fiz alguns erros ortográficos que eu quero corrigir neste vídeo. O primeiro erro está subjacente aos dados da sala. Queremos obter os dados do valor do ponto de instantâneo da sala, então vamos corrigi-lo. Teoh quarto instantâneo valor ponto, em seguida, o segundo erro está dentro de usuários de meio cm. Queremos transformar nossos dados de usuários do DAR FC M em vez de usuário do FC M. Em seguida, se nós rolar para baixo para FC um objeto mensagem aqui. Usamos tokens de registro, e esse erro vem do ritmo de cópia da documentação do firebase. Então vamos removê-lo e vamos colocar tokens e o mesmo celular fazer dentro tokens de falha Não empurre porque queremos ter certeza de que obtemos tokens de nossos tokens, um estupro. Então, se descermos, o último será. Você tem que ser registrado e é isso. Tudo o resto parece bom. Agora. Vamos salvar o arquivo e confirmar nossas alterações. Vamos esquecer tudo, em seguida, obter commit e digamos corrigir erros ortográficos. CEO perfeito no próximo 154. Enviando e exibindo notificações usando funções de nuvem: Ei aí. Neste vídeo, vamos trabalhar com clientes e vamos criar uma janela modelo a partir da qual vamos enviar uma solicitação para nossa função de nuvem e, em seguida, enviar uma notificação para Absi. Usuários. Vamos, vamos voltar para o código B. E primeiro, vamos abrir fogo Base Duchy s e vamos importar pacote de funções. Então, no topo, eu vou derramar funções de barra de firebase de importação. Agora vamos saudar uma nova instância. Então exportar funções const app dar funções. E quando ele abriu, Parenti disse que você pode ver uma região aqui. A coisa com funções de nuvem que eles estão disponíveis em várias regiões por padrão. Eles estão disponíveis na região Leste dos EUA. Para os usuários da Europa, isso não é ótimo. É por isso que precisamos mudar a região fora de nossa função. Para isso, vamos navegar para FC M Dodgy s no lugar onde criamos essa função. E dentro desta definição, vamos adicionar outra cadeia fora de uma região e dentro bolha especificado que esta função será executado na Europa Oeste três região. Você pode especificar qualquer região que você gosta. OK, então Europa Oeste 3 E agora, quando inicializarmos esta instância, precisamos passar pela Europa Oeste 3 para que funcione. E também quando vamos usar esta instância de funções dentro do nosso cliente, ele vai tentar acessar a função de nuvem rial que já está implantada. Mas para o desenvolvimento local, isso não é bom. É por isso que precisamos aqui na verificação inferior Se estamos atualmente dentro do desenvolvimento local , então vamos usar funções. Amma mais tarde que executamos com MP Enron, iniciar dentro da pasta Funções. Então, aqui, se vamos verificar se é o host local e é o host local anteriormente em vídeos Nós exportamos partir daqui nós extraímos Este é o host local valioso do arquivo de serviço criado pelo aplicativo Creek React e agora vamos usá-lo. Certo, então é o anfitrião local. Vamos importá-lo. Então, se este for o caso, então vamos dizer funções, usar funções. EMLeader e precisamos de especificar a Europa para isso. Vamos para a pasta Funções dentro do nosso terminal. E aqui vamos brincar e o PM Ron começar e vamos ver a saída. Tudo bem. Como você pode ver, nosso emulador de funções está sendo executado no host local 5001. Então precisamos especificar aqui http do que host local e 5001. Tudo bem agora, estamos todos prontos com os nossos decaídos. Agora vamos criar o Moto real. Então vamos para a janela de bate-papo Top. E dentro desta pasta vamos criar qualquer arquivo que vamos nomear enviado FC M Bt em Moto Gs. E, na verdade, vamos copiar e colar o código de Vamos navegar para criar o quarto Beat e Moto, então vamos chamar de ser tudo isso e colocá-lo aqui. Agora vamos começar a substituir as coisas. Então, primeiro de tudo, vamos renomeá-lo para enviar FC M Bt e modelo e vamos realmente usar este componente dentro togs índice dentro da pasta superior. Então aqui, em vez de fazer isso, vamos perguntar se nosso usuário é admin, então, por favor, mostre-nos. Mande FC M Bt e Moto. Tudo bem, Bom. Agora vamos começar a substituir o componente. Primeiro, vamos verificar o nosso motile para o nosso formulário, para não termos nome e descrição. Teremos título e mensagem que enviaremos para a nossa função de nuvem para título e mensagem e é necessário. Vamos dizer que o título é obrigatório e o corpo da mensagem é necessário. Ok, bom. Agora vamos excluir esta importação do que o nosso formulário inicial vai ser intitulado e mensagem agora vamos importar usar estado motile novamente. Tudo bem, então temos formulário. O valor está carregando para ele. Rough em submeter. Certo, vamos mudar um pouco. Então, na verdade, vamos excluir essa parte e mantê-la assim. Agora, aqui, dentro do Js seis. Vamos remover isto, Steve completamente. Vamos remover este nome de classe, e vamos deixá-lo como um fragmento de reação. Então, para botão, vamos especificar aparência fora primário e tamanho vai ser extra pequeno do que não vai ser um componente de bloco e cor. Vamos manter a cor padrão. Por isso, para que eu possa, vamos especificar que eu cumpri. Elenco e vamos dizer transmissão mensagem em vez de enviado FC M. Vamos ser um pouco mais criativo. Então, para modelo, tudo bem. Vamos alterar o título para enviar notificação aos usuários da sala Teoh do que para este formulário. Parece bom para o grupo de formulários. Vamos mudá-lo. Teoh Título nome de controle de formulário vai ser título e espaços reservados vai ser inserir título da mensagem de quatro descrição. Vamos mudar para mensagem novamente. Vai ser um componente de área de texto do nosso nome vai ser mensagem. Este nome deve corresponder à nossa chave de estado, que é título e mensagem. Tudo bem, então, por favor, Holder deve ser algo como e a mensagem de notificação. Ok, bom. E por este botão na parte inferior. Então aparência, primário no clique em enviar bloco. Está bem, parece bom. Agora, vamos apenas mudar o texto para publicar uma mensagem assim. Ok, bom. Agora vamos dar uma olhada no topo. Temos alerta desnecessário e também uma importação de firebase necessária. Vamos dizer com vamos voltar para o Chade. E agora temos essa janela moral, então digite um título e uma mensagem. Tudo bem, agora vamos definir a funcionalidade. Então, o que vai acontecer no Submeter? Precisamos enviar um pedido para a nossa função de nuvem. E como você se lembra, nossa função de nuvem é uma função chamável, e usamos funções como deterioradas. É por isso que vai ser tão fácil de fazer. Então vamos colocar o bloqueio kitsch aqui. Vamos colocar de lado está carregando para o topo assim dentro bloco kitsch banal, vamos fazer a próxima coisa Primeiro, vamos criar qualquer valioso enviado FC M e, em seguida, vamos chamar funções como deterioradas que importamos de Firebase Dodgy S. Então vamos chamar https ingênuo. E aqui precisamos especificar o nome da função que queremos chamar, então isso é muito importante. Então dentro togs índice que exportamos enviar função de nuvem FC M. Este é o seu nome. Tudo bem, então vamos copiá-lo. E aqui vamos especificar que vamos chamar enviado FC M função Nuvem. Este método https crédulo, devolve-nos e você função que precisamos chamar, a fim de realmente enviar uma solicitação para a função de nuvem. Tudo bem, este não é o pedido em si. Então, agora precisamos chamar ou invocar comeu areia FC M com dados que queremos passar para a função de nuvem. E então esses dados estarão disponíveis aqui sob esses dados disponíveis. Então o que vamos fazer, vamos chamar um peso do que enviado FC M. e dentro vamos passar chat I d. Como você se lembra, precisamos receber Chad I d título e mensagem. Então, ideia Chet, precisamos primeiro pegá-la. Então vamos colocar aqui e os melhores programas Char i. D. D. Hughes. OK, Bom. Então nós verificamos I d e também precisamos enviar título e mensagem, que é o nosso valor de formulário. Então podemos simplesmente espalhá-lo assim dentro deste objeto, e agora ele vai enviar o pedido. Então, no final, teremos dito está carregando tais bagatelas. Em seguida, vamos chamar valor de formulário sat para o valor inicial. Então inicial para e também vamos fechar esta janela do motor. Então, no caso de qualquer alerta ou em caso de qualquer outro, vamos chamar alerta do que na nossa e, em seguida, nunca encaixar mensagem com a idéia Não. Sete segundos. E também em caso de sucesso, vamos especificar informações de alerta e vamos dizer notificação. O feijão enviou bem? Parece bastante incrível. Agora vamos dar uma olhada, como eu posso ver aqui, eu devo movê-lo para o topo. Tudo bem, vamos navegar. Vamos para a mensagem de transmissão. Vamos especificar algo super e publicar. Mensagem e notificação foram enviadas. Agora vamos dar uma olhada. Se abrirmos o nosso terminal, podemos ver que dentro do nosso terminal direito onde executamos a função de nuvem, podemos ver que a execução inicial terminou a execução, então ele realmente funciona. Agora vamos dar uma olhada dentro do nosso conselho. Não vemos nada. E também talvez vamos tentar enviá-lo mais uma vez para ver o que vai acontecer. E vamos abrir a rede. Então eu disse a mensagem. Em seguida, você pode ver que o pedido está sendo enviado para o Host Chat local. Web up Europa foi três Sand FC um, eu já vi que o resultado é falso. E isso ocorre porque, como você se lembra, dentro de nossa função de nuvem, verificamos os usuários do FC M de dados de sala. Mas neste momento, dentro do nosso banco de dados, se abrirmos nossos quartos, não temos usuários FC M ainda. Precisamos mudá-lo. Então vamos navegar para criar sala Bt e Moto e ouvir o que vamos especificar. Então, para admite, vamos usar também o usuário atual seu i d. Mas também, nós vamos especificar FC um usuários. O primeiro administrador. O criador fora desta sala também receberá uma notificação por padrão. Então vamos copiá-lo assim. Digamos que estamos e agora precisamos modificar o grupo existente, mas que vamos realmente primeiro copiar nosso usuário i d. daqui. Em seguida, vamos clicar neste sinal de mais e digamos que os usuários do FC M. Então, mais uma vez, sinal de adição. Vamos adicionar nosso próprio usuário. E depois para o valor. Vamos pela verdade. Em seguida, adicionamos esse valor. Agora, vamos tentar transmitir a mensagem mais uma vez, então vou dizer algo estúpido. Ok? A notificação foi enviada. Se eu abri meu cônsul agora eu posso ver que eu recebo um novo registro do cônsul, que vem do Firebase Dodgy s. e se eu abrir este arquivo, eu posso ver que ele vem desta mensagem na mensagem. Então eu tenho de notificação, eu tenho corpo e título. Agora, a única coisa que eu preciso fazer aqui é realmente exibir esta notificação de forma mais amigável . Espere. Bem, isso vai ser muito fácil de fazer com brinde ou componente de notificação que vem do nosso terno. O que vamos fazer, vamos importar notificação como brinde do nosso terno. Por quê? Estou usando aqui. Notificação torrou em não notificação porque a notificação também está disponível como valioso global dentro do objeto janela dentro do navegador. Então pode ser confuso e podemos fazer alguma coisa. Então, só para ter certeza de que usamos um componente personalizado, nós o nomeamos dosed. Então aqui dentro na mensagem. Nós vamos servir algo como, como você se lembra, nós temos notificação. Objeto dentro, para que possamos destruí-lo daqui. Notificação. E então vamos ligar novamente vamos destruir o chur desta vez do título da notificação e corpo. Agora temos essas duas chaves e vamos ligar para a porta torrada em quatro. Em seguida, vamos derramar descrição título e descrição vai ser corpo e velho, então duração zero. Então o que ele vai fazer, ele vai cortejar e você componente um componente de notificação do nosso queimado com este título com este corpo, que é a descrição. Mantenha que precisamos passar por esta informação e, em seguida, a duração é definida como zero, modo que nunca vai fechar por si só. Precisamos fechar manualmente esta notificação. Tudo bem, então agora vamos saborear e dar uma olhada. Então, se eu colocar algo como um baixo e, em seguida, este é o corpo e publicou nova mensagem Agora eu tenho esta notificação e é isso. No entanto, há mais uma coisa legal nisso. Se eu clicar em algo como esta mensagem publicada e quando eu clicar neste botão e , em seguida, alternar rapidamente entre toques. Agora vou receber esta notificação. Muito legal, certo? Então é isso. E é assim que vai funcionar. E todos os usuários inscritos nesta mensagem de transmissão os receberão em seus dispositivos. Ou é PC ou dispositivo móvel ou qualquer dispositivo para usar. Mas isso é o que vamos gerenciar no próximo vídeo. Por enquanto, terminamos aqui. Vamos cometer nossas mudanças. Vamos abrir o nosso terminal. Aqui está uma coisa boa. Ele nos dá aviso Firebase dizendo que usando um índice não especificado. Então vamos realmente adicionar, e você indexar para nossas regras de banco de dados. Então vamos abri-lo. E, como você pode ver, considere adicionar índice no valor em tokens FC M. Então vamos para tokens FC M. Então vamos adicionar índice. Então vamos copiar de algum lugar e colocá-lo aqui e Índice em vai ser valor de ponto. OK, então agora vamos publicar essas mudanças. Vamos copiar todos eles. Vamos navegar para as regras do banco de dados, Jason, e vamos substituí-las assim. Ok, olha, marcou. Agora vamos cometer nossas mudanças. Finalmente. Então deixe-me parar com tudo, então eu vou colocar pegar em tudo e então me comprometer. E então eu vou dizer, gerenciar FC M da planta chamada função nuvem e enviou FC M Perfeito. Vejo-te no próximo. 155. Gerenciando usuários da FCM: Olá. Neste vídeo, vamos criar uma nova janela modelo. Nunca perguntará aos usuários se eles querem receber notificações ou não. Vamos lá. Vamos navegar de volta para o código e em Bate-papo Window Top pasta. Vamos criar um novo arquivo. Pergunte FC M Bt e modelo. Vamos completar este componente. Será coberto com o ato Frackman. E como um gatilho, vamos servir o botão Aiken para Aiken. Nós vamos especificar que eu posso componente e para eu posso componente vai citar. Posso citar o podcast. Este I can Button também terá tamanho de colarinho azul vai ser pequeno e também vai ser um círculo. Vamos salvá-lo. Vamos navegar até Index Duchy Sim, dentro da pasta superior e vamos usar este componente dentro desta barra de botões logo antes de uma praia de Detroit e Robert. Vamos perguntar ao FC M Beach em Moto. Vamos dizer esperar e vamos dar uma olhada Agora, Como você pode ver, Eu tenho esta marca quebrada no topo, e isso é porque se abrirmos edição quarto Beach introdução Burr foram para cima no elemento dif. Vamos removê-lo e vamos manter o fragmento de reagir. Agora, se dermos uma olhada. Tudo está bem alinhado. Perfeito. Agora vamos continuar a construir o nosso perguntar FC e batido e Moto. Então vamos definir uma janela de motel aqui. Dentro, teremos cabeça mortal do que corpo e rodapé. Deixe-me especificar todos eles. Então dentro da Heather, teremos o título dos pontos mortais e as pessoas dizem que não são férias de chá. Permissão. Ok, bom. Agora, a fim de exibir algo dentro do corpo, precisamos saber se nosso usuário atual já está recebendo mensagens do FC M. Para isso, precisamos derramar algum outro valor dentro do nosso contexto. Vamos navegar até o Chad Togs. Então esta é Page onde passamos alguns dados de contexto sobre nossa sala atual. Aqui podemos obter nossos usuários FC M, Então vamos pobres usuários FC M valiosos. Em seguida, vamos chamar transformar para matriz do que os usuários atuais sala FC M. Agora precisamos pegar nosso Bullen. Então vamos criar está recebendo FC M e vamos perguntar se FC abusadores matriz inclui US usuário atual . Seu passado condenável. Isto está recebendo FC e Bullen para a nossa corrente do contexto. Agora vamos salvá-lo e dentro perguntar FC M Entre Moto, vamos começar está recebendo FC M de usar gancho sala atual. Certo, perfeito. Mas para seletor, vamos especificar o valor está recebendo FC M Good. Agora, para modelo, precisamos usar o estado mortal. Então vamos usar este gancho de estado modelo e você vai ter, como sempre, está aberto, fechado e aberto. Então, para janela mortal, nós vamos especificar o show propriedade que vai ser aberto no esconderijo. Você vai estar perto. E também vamos especificar outros adereços que não usamos antes, como tamanho. Vamos especificar extra pequeno e também pano de fundo vai ser estático. Tudo bem, agora vamos realmente derramar nossa renderização condicional por dentro, mas antes deixe-me resolver rapidamente este assunto e aqui também, e nós não precisamos disso. Então, dentro do rodapé para evitar esta linha vermelha para um delicioso botão put com texto alto e dentro do corpo colocará renderização condicional. Então vamos perguntar se está recebendo FC M. Então vamos colocar um elemento diff com o nome da classe fora do centro de texto. E dentro deste Dave, vamos colocar eu vir com o nome da classe fora do texto verde e margem inferior três, então eu posso nomear vai ser círculo de verificação e tamanho vai ser cinco vezes grande. E ao lado disso, eu posso Nós forneceremos o título H seis com texto. Você está inscrito para transmitir mensagens enviadas por ad Mons fora desta sala. Tudo bem, Bom. Agora, se não estamos assinando mensagens, em seguida, vamos exibir outro ao vivo novamente com o nome da classe fora do centro de texto desta vez irá exibir outro ícone com classe. Nome fora do texto Azul e margem inferior três também. Então eu posso nomear vai ser questionado. Círculo e tamanho novamente cinco vezes grande. Agora, ao lado deste Aiken novamente, h seis título. E você quer assinar minhas mensagens enviadas por ad mons fora desta sala? Ok, bom. Ao lado desta renderização condicional, vamos derramar outro texto. Então vamos colocar tag p e classe. Nome vai ser margem top dois, e vamos dizer para receber notificações, certifique-se de não permitir férias em seu navegador. Tudo bem, Bom. Vamos saborear e dar uma olhada. Então, antes de podermos fazer isso, vamos derramar no manipulador clique para o botão Aiken. Vamos abrir e dar uma olhada. Ok, então se eu clicar neste botão agora eu tenho notificações. Permissão? Você está inscrito para receber notificações. Certifique-se de permitir notificações no seu navegador. Além disso, seria bom se tivéssemos algum tipo de valor que indica se temos a permissão ou não. Porque se abrirmos essa informação lateral aqui, restringimos permissões diferentes, como localização, microfone e notificações. Então, se isso estiver configurado para bloquear, não seremos capazes de receber nada. É por isso que é bom exibir aqui. Mas que a permissão é concedida não foram para isso. Vamos colocá-lo ao lado deste indicador de permissão da tag P. Então, vamos dizer permissão. Em seguida, vamos embarcar cólon e, em seguida, colocar renderização condicional. Então vamos colocar notificação e notificação é o objeto global dentro da janela dentro do navegador. Se eu, no entanto, você pode ver que isso é notificações ap I Então, se a permissão de ponto de notificação é igual a dois grunhidos, então eu vou exibir um elemento girado que vai dizer grunhir e vamos colocar um nome de classe fora Texto verde. Caso contrário, se não tivermos a permissão, vamos exibir span com texto de noite e o nome da classe vai ser texto lido. Perfeito. Mas agora posso guardá-lo porque parece que tenho um lugar melhor. Tudo bem, vamos fazer este Pitak até o fim assim. Ok, parece bom. Agora vamos dar uma olhada. Se eu abrisse esta janela agora, eu tenho permissão na frente. Parece que vai agora precisamos definir nossa funcionalidade. Então, dentro do rodapé. Vamos primeiro colocar um botão de fechar. Então deixe-me fazer um recapitalizado e no clique vai ser perto. E logo antes deste botão, vamos colocar nossos botões principais para funcionalidade. Então vamos perguntar se nosso usuário está recebendo FC M. Então vamos colocar botão com texto. Mudei de ideia porque, como se lembra, temos uma pergunta. Deseja subscrever mensagens por cores? Vamos especificar verde e para unclipped vamos criar em cancelar função apenas em um momento . Caso contrário, se não recebermos nenhuma notificação, citaremos outro botão. Mas texto Sim, eu quero me inscrever. Tudo bem. Para unclip vamos derramar sobre, exceto e para uma cor. Trabalharemos verde também. Tudo bem, vamos salvá-lo. E agora vamos definir nossas funções primeiro. Vamos derramar. Cancele em. Cancele e aqui vamos fazer referência ao nosso banco de dados. Então vamos colocar banco de dados que importamos do arquivo firebase de referência. E as pessoas especificam quartos, sala de corte I D ou chat I D que obtemos de usar Paramus Hook. Então, chat i d. Ele recebeu do uso permanente. Vamos mover esta importação para o topo do que estamos indo para referenciar usuários FC M e para filho, que está fora do usuário atual. Vamos importante fora do usuário atual que eu d Não remover. Vamos simplesmente remover este objeto do nosso banco de dados. Bom. Agora vamos definir a segunda função, que está em, exceto e nacionalidade diferente vai ser bastante semelhante licious. Entendido, Nipper. E em vez de remover esta criança, vamos definir isso para a verdade. Tudo bem? Perfeito. Agora vamos realmente testado. Então, vamos abrir o nosso motile e aqui vamos clicar em Eu mudei de idéia e agora você pode ver que a condicionalidade entrando funciona. E se olharmos dentro do banco de dados, vamos para os quartos agora não temos usuários do FC M. Se eu clicar em sim, eu faço. Agora temos usuários FC M com o meu usuário i d insight, Mas para torná-lo um pouco mais amigável. Vamos realmente definir outra cor para o nosso botão Aiken. Então, vamos dizer aparência. Se o nosso usuário estiver recebendo FC M, então vamos derramar aparência padrão. Caso contrário, vamos colocar fantasma e vamos dar uma olhada no que vai acontecer. Então, se eu disser o que agora eu tenho esta cor azul aqui com a aparência normal. Tudo bem, então se eu mudei de idéia agora eu tenho essa aparência fantasma sem a cor dentro do fundo. Ok, bom. Então é isso. É assim que podemos gerenciar nossos usuários, mas eles querem se inscrever ou não. Então, se eles não estão assinando, isso significa que eles não receberão qualquer notificação que são enviados por esta forma moral. Tudo bem, então eu acho que é isso para este vídeo. E esta é a hora de comprometermos nossas mudanças. Vamos abrir nosso terminal e então vamos pegar Dar e nos comprometer. Vamos um homem idade FC M usuários com o pedir FC M vtm Moto perfeito para terminar esta jornada. Vamos Bush tudo online para nos levantarmos. Consiga a reunião de origem de Bush depois de terminar. Vamos executar, firebase implantar e desfrutar do nosso aplicativo de bate-papo online. Fico feliz em dizer que estamos completamente terminados com este projeto. Implementamos tudo o que queríamos. As notificações em tempo real, funções de administrador, presença do usuário. Temos tudo no lugar. Haverá mais alguns vídeos sobre o conceito de reagir que não cobrimos o seu nestes três projetos. Mas, no entanto, espero que tenha sido uma experiência valiosa para nós dois. E espero que este curso lhe dê o que veio buscar. Obrigado por isso. Tempo e paciência. Te vejo na próxima vez. 156. Características essenciais do React: Ei, nesta seção mais, vamos cobrir recursos de reação que quase todos os aplicativos de reação regular de produção têm . Mas não tivemos a chance de usá-los em nossos projetos. Tudo o que será abordado aqui será aplicado ao nosso aplicativo final de chat do projeto para nos ajudar com o código de referência dupla oficial reagir documentação. Eu recomendo que você leia você mesmo para entender melhor como reagir funciona. Vejo você no próximo vídeo. 157. Portais de reato: Santificar. Nosso primeiro vídeo será sobre reagir. Portais e portais é apenas uma maneira Teoh. Renderizar algo com reagir fora def com fruta ideal. O que quero dizer, se abrirmos nosso aplicativo de bate-papo e se inspecionarmos nossos elementos, sabemos que todos os nossos elementos, todos os nossos componentes, nosso aplicativo vai sob este dif com idéia escreveu direito, No entanto, vamos dar uma olhada quando abrimos uma janela modelo onde ele será renderizado. Então, se eu abri isso através de oito novas salas de bate-papo, você pode ver isso aqui na parte inferior. Eu tenho esse diálogo de função def, e se eu abri-lo e inspecionar, você pode ver que, na verdade, meu novo modelo Chatham está sendo processado fora desta rota. Então é para isso que os portais são usados. Isso é útil para algo como janelas de modelo ou dicas de ferramentas ou pairamentos. Eu não sei nada que deve ser locatário fora do tratamento principal componente. Isso é muito útil quando lidamos com propriedade CSS índice Z. Então, nunca vamos voltar à documentação e vamos olhar através de exemplos aqui você pode ler palavras que eu acabei de dizer alguma vez olhando para este exemplo, pode ser muito complicado entender o que está acontecendo. Então, em vez de copiar, passear, classe motile da documentação, vamos abrir nosso código. Eu já Irã o aplicativo e outros componentes. Vamos criar um novo modelo de arquivo. Vamos criar um novo componente. E aqui, em vez de devolver este Dave da documentação, podemos ver que somos capazes de usar reagir, não criar método portal. Então, em vez desta definição, vamos voltar. Crie portal e ele será importado automaticamente para nós. E se eu abrir festas, como eu posso ver que aqui eu tenho Crianças e, em seguida, elemento Tudo bem, recipiente. Então, para Crianças, vamos colocar Crianças que passarão para este componente mortal. Então aqui vou destruir seus filhos. E depois passarei para criar o Porto do que o nosso contentor. Deve ser outra div que o problema define dentro do índice html. Então aqui nós já temos este diferente com idéia Satu Road. Agora vamos criar outro dia se isso for um contêiner para nossas janelas modelo. Tudo bem, então aqui vamos criar Dave e eu serei a rota modelo. Vamos salvá-lo e dentro do modelo de togs. Se abrirmos documentação, podemos obtê-lo usando documento. Obter elemento por I.D. I.D. então vamos copiar esse. Vamos colocá-lo aqui no topo e para criar portal como um segundo argumento, vamos passar rota moral. Certo, Perfeito. Agora vamos salvá-lo. E diz que reagir é declarado. Nunca usei. Tudo bem, então talvez vamos removê-lo. Agora vamos abrir. Talvez página de assinatura. E aqui, vamos dar as boas-vindas ao bate-papo. Vamos fazer a visita deles dentro da janela do modelo. Então aqui vamos colocar modelo importado do nosso arquivo que criamos, não do nosso terno. Então vamos remover essa importação, e eu quero importá-la do nosso arquivo. Tudo bem. Parece que importa do nosso terno. Vamos importá-lo manualmente do modelo de componentes. Perfeito. Então, dentro deste modelo, vamos colocar nossa def com centro de texto. Agora, se nunca voltarmos ao nosso aplicativo Se terminarmos a sessão agora, você poderá ver as boas-vindas. Chad está localizado no fundo e se eu for aos elementos e inspecionar minha árvore idiota aqui no fundo, posso ver a rota mortal. E dentro desta rota modelo, confinamos nossas boas-vindas à cadeira sob o centro de texto. Então este é um Este é usado em suas bibliotecas de olhos como o nosso CLR para janelas de modelo e para dicas de ferramentas . Por exemplo, se tivéssemos que criar, eles reagem aplicação sem usar biblioteca lágrima I e tivemos que implementar janela móvel. Muito provavelmente usaríamos portais de reação porque eles são renderizados fora do nosso principal deleite confiante. Você pode achá-lo mais prático Onley quando você entrar nele em um exemplo do mundo real. Tudo bem se você não entender completamente. Mas confie em mim, este é o conceito chave que você deve pelo menos conhecer. Ok. Obrigado. Vejo você na próxima. 158. Limites de erros: Ei aí. Neste vídeo, vamos falar sobre seus coqueiros. Vamos voltar para o tribunal e abrir a página de sinal aqui. O que vai acontecer se vamos dizer, lançar um erro dentro deste componente? Vamos pobre lançar novo erro. Algo ruim aconteceu. Agora vamos dizer o que e vamos dar uma olhada. Se eu refrescar a tinta, podemos ver que temos um nunca e algo ruim aconteceu. E a coisa é que estes entram está preso. Isso significa que ele é chamado por reagir, mas não por nós, e, eventualmente, reagir será a quantidade de toda a árvore competente, que é realmente ruim se tivermos uma produção pronta por aplicação para evitar que temos melhores coqueiros que são limites são componentes que capturam todos esses tipos de letras e a exibição no fullback You I, por exemplo, uma mensagem que estes paginados falharam. Por favor, atualize-o. Então, se abrirmos a documentação, limitamos um exemplo oficial de como criar um componente de árvore de pão de resposta simples. E para a maioria dos casos isso é suficiente. A menos que você tenha um registro de erro realmente sofisticado ou eu não sei nada o que eu propus fazer eu quero ir para uma demonstração ao vivo? Então eu quero que você abra este exemplo e daqui eu vou copiar isso. Digite classe Bunge re. Então deixe-me copiar tudo isso. Então eu vou abrir a decodificação e, em seguida, dentro de componentes, eu vou criar um arquivo de sempre Bun gery. E dentro vou colocar este componente baseado em classe. E não seja assustador sobre este componente que é baseado em classe. Vou explicar tudo o que acontece aqui. Então deixe-me importar, reagir de reagir. E também temos um monte de sim avisos de comprimento. Vamos desativá-los todos. Vou apenas clicar na correção rápida e desativada para todo o arquivo. O mesmo que farei aqui. Agora vamos salvá-lo. E o que está acontecendo aqui dentro do construtor que definimos em seu estado, que é um objeto com sempre e informações de erro do que usar uma ação competente Catch, gancho de ciclo de vida ou evento de ciclo de vida. Nós detectamos qualquer erro que está acontecendo dentro deste componente, ok? Ou aos seus Filhos. Quando temos qualquer erro, atualizamos esse estado e, em seguida, dentro do método de renderização. Se tivermos algum erro dentro do nosso estado, que é jogado o fullback ey. E caso contrário, se tudo estiver bem, nós simplesmente renderizamos todos os seus Filhos. Ok, bem simples. Agora, a fim de usar este editor, precisamos envolver toda a nossa árvore dentro desta carta. O Bunbury. Então vamos abrir Abdel Gs. E aqui eu vou para sempre grupo que nós componentes que criamos. Deixe-me salvar tudo isso. Em seguida, navegarei de volta para o meu aplicativo. Vou refrescar o amplificador e agora ainda tenho esse aviso de reação. Isso é porque estamos no barco de desenvolvimento. No entanto, se eu fechá-lo agora, em vez de assinar página, Eu tenho este algo uma mensagem errada com os detalhes dentro. E se eu abrir minha outra árvore de pão, eu posso ver que em caso de algum erro, isso é exatamente o que eu estou renderizando e pode ser um viés personalizado. É assim que conseguimos capturar qualquer outro dentro do Y em cada aplicação pronta para produção . Isto é uma obrigação. A coisa legal sobre nossos limites é que podemos criar vários componentes. Por exemplo, agora colocamos a árvore Herman global. Se qualquer erro dentro da árvore competente será produzido do que ele será capturado por este limite de letra e, em vez de fora de qualquer componente. Ele exibirá esta mensagem com algo quando bêbado. Digamos que temos um monte de componentes e botão ou esmagado, se não barra caiu. Não queremos remover tudo certo para essas situações. Podemos colocar vários outros limites, por exemplo, por componente ou por página. Então, para a página de assinatura, eu posso puxar sua própria árvore de pão entrar assim. Então eu posso criar outro componente com outro mercado para sempre. E então eu posso esfregar outra página em volta de outra na árvore de pão dela. Assim, desta forma, se o erro será produzido dentro da página inicial, ele será capturado por estes outros bun DRI e, em seguida, o U Y. Isso está listado dentro desta árvore de pão letra será exibido. A questão é por quê? E correu bem. Evers podem ser produzidos por qualquer coisa. Pode ser qualquer erro dentro do código que não controlamos ou simplesmente evitamos. Ou talvez possa ser uma rede de sempre, por exemplo, se algo precisa ser acessado online. Mas do nada, Internet caiu e o componente não conseguiu renderizar desta forma, ele será enjaulado por enter bun tree e é muito importante entender que esses tipos de erros não serão capturados por nunca. Bun árvores em seus coqueiros pegar outros Onley relacionado Teoh renderização. Agora eu acho que nós precisávamos disso algum tipo de Bunbury melhor dentro do nosso aplicativo de bate-papo. Então acho que é uma boa hora para cometermos nossas mudanças. Então vamos derramar este trono. Sua companhia aérea está assinando e vamos colocar uma árvore de pão global para o nosso aplicativo de bate-papo e vamos cometer nossas mudanças. Então eu vou servir. Tudo bem, deixe-me reiniciar o terminal. Eu vou colocar, obter em tudo e, em seguida, começar cometer e, em seguida, adicionar melhor árvore de pão. Perfeito. Espero que tenha sido abrangente e não muito complicado. Vejo-te no próximo. 159. Dividindo: Hey lá nesta bolha de vídeo, falar sobre a divisão de código no modo de reagir, divisão é firmemente acoplado com o carregamento preguiçoso em reagir, morto, divisão significa para componentes de carga preguiçoso, dependências ou talvez até mesmo CSS arquivos. Se lermos a documentação, podemos ver esta seção de agrupamento onde diz que sempre que construímos um aplicativo, temos o arquivo JavaScript final. E, de fato, se olharmos dentro do nosso projeto e formos para o mais recente script estático e ciumento construído aqui, limitaremos alguns trabalhos, ótimos arquivos. E como você pode ver, eles são ampliados e, ao mesmo tempo, eles são bastante grandes. Então é aqui que a nossa lógica vai. Mas com o carregamento a laser, somos capazes de criar mais pedaços de nossa aplicação. E desta forma, podemos colocar uma carga nossos pedaços JavaScript em Lee quando eles são necessários. Por exemplo, se você olhar dentro de nosso aplicativo, basicamente não precisamos fazer login na página agora. Precisamos de Onley quando não estamos autorizados, certo? Então, faria sentido para sinal de carga preguiçoso e componente de página. Então, se vamos para a documentação e se nós rolar para baixo para o exemplo real com reagir, preguiçoso reagir Lisi é uma técnica dentro reagir a componentes de carga preguiçoso. Podemos usar este exemplo para carregar preguiçoso nossa página de login. Vamos copiar esta linha de código do que eu vou navegar para Abla GS Place onde renderizamos o componente de assinatura aqui. Vou pagar este outro componente e vou substituí-lo pelo Sinan. E, em seguida, vou copiar o passe para entrar na página. E então eu vou realmente importar preguiçoso bem de reagir em vez de usar tinta como essa. E também eu preciso importar suspeitos como podemos ver na documentação, porque quando nós preguiçosos, baixos fracos Ojul, pode levar alguns segundos ou milissegundos para carregar este módulo. E enquanto ele está sendo carregado para evitar carne, podemos usar algum fullback. Você eu algo como carregar. É por isso que precisamos fornecer suspense sempre. Então deixe-me copiá-lo, e meu pregador está faltando. Então deixe-me cancelá-lo e realmente iniciou o aplicativo. Talvez funcione. Ok, então eu vou derramar suspeitos que eu iria assinar na página e eu vou colocá-lo assim agora eu posso almoçar meu aplicativo de volta e deixe-me salvá-lo e Agora nós devemos usar entrar assim com suspeitos e vamos remover a importação antiga página de início de sessão desligado. Agora, se eu guardá-lo, também preciso importar suspense. Agora, se eu disser onde e se eu navegar de volta para o tribunal se eu atualizar o aplicativo se eu clicar em inspecionar e se eu abri o toque de rede, deixe-me sair e prestar atenção. Qual arquivo será carregado? Então, se eu clicar neste botão, você viu esta pequena cintilação com carga def que colocamos como uma volta completa aqui enquanto esta queda para trás você. Eu estava mostrando que nós realmente carregamos o pedaço do nosso casaco. E se abrirmos aqui, confinamos nossos EUA ou vemos páginas de assinatura. Então é isso que significa codificar dividir nosso aplicativo. Se você construir um aplicativo realmente grande, provavelmente quando alguém lança seu site pela primeira vez, a maioria de seus componentes provavelmente não são necessários. Esta técnica é realmente importante para entender. E um bom exemplo seria apenas abrir o lado do rap do Twitter e ver que em todos os lugares quando você apenas carrega o site, você pode ver spinners que eles usam preguiçoso carregamento muito para que eles preguiçosos carregam todos os componentes para reduzir o tamanho inicial do pacote porque realmente importa. Se eu atualizar o aplicativo, você pode ver que um monte de arquivos foram carregados aqui, como um bloco principal, e queremos manter o Chunk principal o menor possível porque o Senhor inicial fora do site importa. Tudo bem, então isso é sobre carregamento a laser? Espero que tenha sido abrangente. Agora vamos realmente confirmar nossas alterações para o aplicativo de bate-papo. Então vamos servir, pegar o Dar e depois nos internar. Adicionar preguiçoso e flutuante CEO perfeito no próximo. 160. Conclusão: Olá. Agora você sabe todas as coisas modernas necessárias para criar um grande aplicativo de reação pronto para produção. Dê um pouco mais de prática e você definitivamente reunirá tudo o que cobrimos . Aqui está uma tarefa para você. Percorra a documentação de reagir e confie em tópicos que você não ouviu durante o curso . Há muitos detalhes sutis que não são vistos no primeiro copo. Certifique-se de entender por que você está usando essa técnica. Quanto a agora, terminamos com esta seção. Vejo-te no próximo. 161. Resumo - Conhecimento que você ganhou: Olá, Você fez muito bem. Você constrói três projetos de reação separados de complexidade diferente. Você pode orgulhosamente dizer que você tem experiência de desenvolvimento reagir. Agora vamos resumir o que você aprendeu neste curso. Dividirei tudo em seu próprio contexto. Os tribunais começaram com coisas mais gerais onde você olhou para diferentes tipos de renderização do site . Pode AP olhos dado os exemplos do mundo real sua engrenagem, sem cursos de acidente GS e JavaScript modernos e, em seguida, preparou-se para começar a trabalhar com reagir em nosso primeiro projeto. Tick tack para você conhecer primeiro componentes React, sondas, estilos, estilos, ST Dynamic, você I e desenvolvimento de Flow. Em geral, você criou um projeto de reação simples que demonstra noções básicas fortes. Com bilheteria, você mudou para um aplicativo de reação mais complexo, trabalhando com um P I externo e gerenciando cenários primitivos conhecidos . Usando três cozinheiros AC, você aprende o conceito de multidões dinâmicas e dados remotos trazendo você para como otimizar e analisar componentes de reação, CIA diz em GS ou componentes estilizados não são estrangeiros para você a partir de agora. Até o final deste projeto, você tem típico aplicativo reagir que requer re mais abrangente reconhecer No último aplicativo de bate-papo projeto. Você começa a conhecer a base de fogo em primeiro lugar. Você fez um ótimo trabalho na gestão do estado global com contexto. AP I Você experimenta situações confusas e não primitivas que exigem compreensão avançada de reagir. Gerenciar estilos você mesmo nem sempre desejável. É por isso que agora você entende o significado de seus componentes Y, bibliotecas, usuário, estado e páginas privadas são coisas normais para você agora. E ganchos de reação é a sua arma principal. Vários s recuando fora do curso. Pague menos com o mínimo de esforço. No final do chat up, você cria um aplicativo Web pronto para produção com tecnologias atualizadas. Havia também uma pequena sala fora reagir conceitos onde olhamos para eles separadamente e aplicamos ao nosso projeto final. Depois de tudo isso, você deve estar confiante trabalhando com reagir e é eco sistema. Haverá sempre esse sentimento de que o seu conhecimento não é suficiente. E isso é bom. Todo desenvolvedor tem esse senso. Não há limite para a perfeição. Estas foram as coisas que você aprendeu neste curso. Vejo você na próxima vez 162. Movimentos do futuro: Olá. Vamos falar sobre seus próximos passos após o discurso. Não há um roteiro certo para desenvolvedores da Web, mas aqui estão minhas sugestões e recomendações. Primeiro de tudo, aprenda datilografia. É uma linguagem construída em cima do JavaScript. Ele traz sistema de tipo para o projeto, e no final do dia, ele vai aumentar a confiabilidade do código. Google quatro Reagir artigos datilografados e começar com estes integrados em um projeto de reação simples para entender por que é incrível. Em seguida, dê uma olhada em patos re. Você já sabe o uso. Reducer Hook Read Acts é uma biblioteca de gerenciamento de estado global que usa a mesma abordagem como redutor usado. Tem uma curva de aprendizagem, mas com ganchos reagem e redox para criança, Redox tornou-se mais abrangente. Muitos tutoriais e facilidade forçada Redox, mas na maioria das vezes você não precisa dele. Ao mesmo tempo, será realmente uma boa prática aumentar seu valor como desenvolvedor. Google para qualquer artigo sobre redução moderna com três patos toolkit. Se você quer crescer como um desenvolvedor reagir, você definitivamente deve começar a olhar para o próximo GS e Gatsby. Esses dois são frameworks construídos sobre reagir, e ambos destinados à renderização do lado do servidor. Sistema ecológico incrível, bons tutoriais. Eles têm tudo para lhe dar o mais confortável possível desenvolvimento e forçar-se a construir um A p I sem GS, nenhum conhecimento Jess é necessário em todos os lugares, seja um back-end JavaScript ou apenas script de fundo. Encontre qualquer artigo sobre como configurar o GS expresso e nenhum GS. Faça você mesmo que aumentou esse conhecimento fazendo mais prática no final do dia. Saiba mais sobre testes ao fazer alterações. Para decodificar é importante não quebrar nada. É por isso que os testes existem com ferramentas modernas. O teste é muito simplificado e agradável. O teste é importante, mas o mais importante, é testar em Lee o que realmente precisa ser testado. Google Para qualquer artigo relacionado a brincadeira ou teste de reação enzimática. Leia mais sobre segurança fora do aplicativo Web, especialmente sobre Jason Webb tokens, cookies e armazenamento local. Proteger backend também é uma coisa, mas para isso começar a baixar togs, nenhum banco de dados SQL como Mongo, DB ou firebase é fácil, mas eles gostam de consultas e estruturas poderosas ao construir. E não, ela voltou e sabiamente decidir sobre o DB. Pergunte aos seus bancos de dados são mais preferíveis em vestido pose de grande escala. Pergunte L e Mongo db são bastante populares hoje em dia. Mais atenção também é dada ao enxerto ul. Uma vez que você se sente confortável sem xadrez e descanso AP olhos começar a pensar em enxerto. Você vai É mais flexível quando há muita solicitação com a forma de dados dinâmicos Warren Cloud Computing e desenvolvimento off wraps usando serviços de nuvem, ele não vai mudar a pilha de desenvolvimento subjacente, por exemplo, Reagir e observar o GS, mas ele lhe dará serviços que permitem implantar e gerenciar o APP. Implantação sem servidor ou armazenamento em nuvem são exemplos de serviços em nuvem. Dê uma olhada em provedores de nuvem populares e escolha um. Torne tudo automatizado com integração contínua e continua a entrega. A entrega permite automatizar o processo de implantação. Por exemplo, quando você envia uma nova alteração e se levanta, o APP será implantado automaticamente continua. A integração vai antes de continuar a entrega. Ele basicamente define o modelo fora do novo código Push para o código principal. Este tópico não é tão fácil de entender. Então sinta-se livre para ler qualquer artigo e ter um monte de perguntas. Estas são as minhas recomendações. Sinta-se livre para escolher sua própria direção. Vejo você na próxima vez