Transcrições
1. Trailer do curso: Olá pessoal, e
bem-vindos ao Discourse. O objetivo deste
curso Reactjs é apresentar as ferramentas e conceitos necessários para
começar a criar aplicativos
web reais Sou Daniel e
serei seu instrutor. Eu faço desenvolvimento web
há mais de 18 anos, tanto em organizações grandes quanto
pequenas, e ainda adoro isso. Você pode ler mais sobre mim
no meu site, GSCrafto. Comecei a
aprender a
programar tentando criar
meus próprios videogames. É por isso que acho que aprender deve ser
divertido e quase
a mesma sensação que você tinha quando
criança quando brincava
e descobria coisas novas Ao final deste curso,
criaremos o
seguinte jogo usando VGS Será um jogo de pedra, papel e
tesoura para cada jogador, o jogo escolherá um sinal aleatório e também
decidirá o vencedor Ao criar este jogo, analisaremos
várias imagens das melhores práticas do React e também de como evitar armadilhas
comuns O curso também vem com este belo manual imprimível que você pode usar posteriormente
para facilitar a consulta Seguindo o conteúdo
dos vídeos aqui, há mais de 35 páginas
inteiras com código, exemplo, recursos ou diagramas, para que você possa ter uma melhor
representação visual do
que está acontecendo Eu trabalhei bastante neste, espero que seja útil. Vamos começar a ver as aulas.
2. Introdução do curso: Antes de começarmos
a codificar de verdade, gostaríamos de definir
algumas coisas Primeiro de tudo, como
usar este curso. As informações no discurso são bastante densas para obter
os melhores resultados Meu conselho será fazer esse
curso duas vezes. Na primeira vez, obtenha uma
visão geral do curso
e, na segunda vez, faça
o exercício real. Cada capítulo vem com um arquivo inicial e final que
facilitará o
acompanhamento do conteúdo. Eu recomendo que você codifique manualmente , pois isso tornará as coisas
mais fáceis de lembrar. Neste curso,
usarei o VS Code e o Google Chrome porque essas
são minhas principais ferramentas preferidas, mas você pode usar qualquer outro ID ou navegador com o
qual se sinta confortável. Além disso, temos uma configuração muito
mínima. Sem necessidade de trabalho definido,
sem módulos NPM. Na verdade, você pode simplesmente visualizar a fonte e
obter o código que está sendo executado no
navegador, o conhecimento necessário. De uma perspectiva real, este é um curso
amigável para iniciantes Mas se você não sabe
nada sobre react, pode fazer sentido fazer meu outro curso para iniciantes
sobre react que tenho aqui Espera-se que você saiba um
pouco sobre tópicos
como qual é o componente ou como uma
variável de estado de reação funciona. Considere isso como um curso
que fornece um modelo de pensamento sobre
como criar aplicativos reais. Veremos as melhores práticas,
criaremos bugs e também veremos como
corrigi-los. Trechos de Co Pessoalmente, não
gosto de cursos longos. Acho que nunca concluí um curso com
mais de 2 horas. Para reduzir o
tempo deste curso, defini vários
trechos de código como este Você pode ver todos
eles aqui na pasta de código
do VS, onde
tenho todos os trechos de código
que uso durante o curso O motivo para definir todos
esses trechos de código é porque
é muito difícil
para mim falar em um idioma estrangeiro e escrever
código ao mesmo tempo Mas também quero economizar o tempo em que você está
apenas me observando, como eu digito coisas
no editor de código. Com isso resolvido, vamos passar para nossa primeira lição, na
qual usaremos react, render e react to root para criar a estrutura de nosso
aplicativo
3. Renderizar o aplicativo com o ReactDom createRoot: Vamos dar uma
olhada no que temos
no modelo inicial
do discurso Existem essas importações simples. Aqui estamos apenas
importando o Reactome e Babel como fizemos
no passado em janeiro Aqui também temos um bloco de
script que é de texto Babble não é
Javascript é texto Babble E a razão para isso é que precisaremos do babble e também dessa importação para poder
escrever X em nosso código A. Eu criei isso a ideia de não
complicar demais as coisas, não começar com módulos MPM, servidores
web, ferramentas
ou coisas assim Por enquanto, temos apenas
esse arquivo HTML simples de
índice simples. Agora vamos escrever nosso
primeiro componente de reação. Esse componente de reação
será denominado app. Em geral, o aplicativo é o ponto de entrada para
qualquer aplicativo de reação. Vou escrever aqui um aplicativo constante. Este aplicativo é uma
função simples que
retornará algo como
hello do aplicativo react. A propósito, o que
você vê aqui é x. Isso será interpretado pelo Babble e será traduzido
em Javascript simples Neste ponto, se eu salvar e atualizar a página,
nada acontecerá A propósito, criamos esse
div com a ideia de root Este servirá como o contêiner principal
para nosso aplicativo de reação Agora, dado o fato de
que queremos inserir o react Ap
dentro desse mergulho, a primeira coisa que
preciso fazer é vir aqui e escrever uma nova
variável chamada container. Esse contêiner será igual ao
elemento de obtenção do documento pela raiz do ID. Eu vou ter como alvo esse de. Em seguida, precisarei
criar uma nova raiz. Para isso, escreverei const root. Este é igual a
react create root. Vou dar como parâmetro o contêiner que
acabei de criar
na linha anterior. Finalmente, adicionarei uma
nova linha onde
direi rotear Render App Render
dentro dessa rota, este aplicativo a partir daqui. Se eu salvar e
atualizar a página, veremos que agora temos esse lindo olá
do Reactapp O conteúdo que estava antes
na rota de ID agora foi substituído pelo
conteúdo do nosso React, falando dessa renderização raiz. Isso foi introduzido em
versões mais recentes do React antes. Era outra sintaxe, mas esta vem com algumas melhorias de
desempenho Adicionarei no manual
deste curso o link para
um artigo que aponta algumas das atualizações
introduzidas na renderização raiz. Legal. Fizemos do nosso
primeiro um componente. seguir, veremos como criar os componentes necessários para criar
o jogo real.
4. Andaimes os principais componentes: Agora que criamos
nosso aplicativo Act principal, vamos dar uma outra olhada em
nossa arquitetura de componentes. É assim que o jogo
ficará no final. Como podemos ver aqui, temos três tipos
de componentes. Em primeiro lugar, existe
o componente player. Esse componente tem
duas instâncias, uma para o jogador vermelho e
outra para o jogador azul. Há também esse quadro de resultados que mostrará quem venceu o jogo. Finalmente, há
o componente do jogo que incluirá tudo isso. Vamos agora fazer
o andaime para todos esses
componentes Vou voltar para
o índice HTML. A primeira coisa que vou fazer é vir aqui e criar um componente de jogo. Para isso, vou escrever um jogo
constante. Essa é uma função,
uma função básica. Assim como o componente do aplicativo, ele terá o
seguinte conteúdo. Vou escrever aqui um mergulho que só retornará, por
enquanto, esse texto simples Agora, no aplicativo, em vez
de retornar esse H, retornarei uma nova instância
do componente do jogo. Se atualizarmos,
veremos agora que o que temos aqui é esse conteúdo que declaramos
no componente do jogo Mas isso não é suficiente. Se eu voltar aqui, veremos que dentro
do componente do jogo, há jogadores e
também esse tabuleiro Resu Vamos criar
esses dois também. Em seguida, criarei o componente
player. Este será nomeado jogador. Será uma função que retornará
algo assim, apenas com um texto simples. Finalmente, há também o componente da placa de resultados
que também será uma função. Dentro dessa função, direi que ainda não há resultados. Porque aqui
no quadro de resultados, precisaremos mostrar
quem venceu o jogo. Vamos entrar no
componente do jogo aqui, criar todo esse
arco de componentes. Em primeiro lugar, precisarei de duas instâncias
do tipo player. O que vou fazer aqui é criar uma instância e a segunda
para o outro jogador. Em seguida, também adicionarei esse quadro de resultados
que criamos. Se dermos uma olhada final aqui, veremos que também precisamos
desse botão para iniciar o jogo. Eu vou voltar aqui. Aqui vou escrever apenas
um botão HTML simples. Este não é um componente, é apenas um
elemento HTML simples. Eu vou economizar. E agora, se atualizarmos, veremos que
temos
dois componentes de player,
o botão e, finalmente,
a palavra resultante Mas, por enquanto, nossos
componentes de player são exatamente os mesmos, eles só têm esse texto
padrão dentro deles. Na próxima lição,
veremos como podemos personalizar esses
componentes usando adereços E também como ensinaremos
nossos componentes a escolher um elemento aleatório entre
pedra, papel ou tesoura
5. Como adicionar acessórios: Agora que temos o andaime
dos componentes pronto, vamos dar uma olhada no
nosso exemplo final Novamente, você verá que um componente do player é
vermelho e o outro é azul. E também têm alguns
símbolos Ramble atribuídos a eles. Em nosso status atual, os dois componentes
parecem exatamente iguais. Eles são apenas uma div
com um texto padrão. O que eu quero fazer com você
nas próximas duas lições
é, antes de tudo,
atribuir parâmetros a esses componentes para saber que este é
vermelho e o outro é azul. E também na próxima lição, veremos como primeiro desenhar alguns elementos aleatórios
para esses componentes. Vamos começar com os parâmetros do
componente. A primeira coisa que precisaremos
fazer é vir aqui na declaração
do componente
e atribuir uma cor a eles. Aqui, direi que
quero uma cor azul
para esse jogador. A seguir, direi
que quero uma cor vermelha. É assim que enviamos um parâmetro nesse valor para o componente
real. Para lê-los, precisarei aqui adicionar
um novo parâmetro props Esse é um parâmetro padrão que cada componente da função
pode receber aqui. O que podemos fazer é apenas ler o valor desse
parâmetro que enviamos. Então, podemos ver aqui
adereços dessa cor, digamos que quando
atualizarmos, veremos aqui que temos componente de
cor azul e
o outro é Mas podemos dar um passo à frente. Podemos tirar proveito
das instruções de estruturação do Javaskip O que posso fazer aqui
é adicionar
a declaração de reestruturação do Colo Em vez de ter
aqui adereços dessa cor, posso simplesmente dizer que agora quero a cor e as coisas funcionarão
exatamente da mesma forma que antes Mas podemos até dar um
passo à frente e fazer toda
a desestruturação diretamente na declaração
da função O que eu quero dizer aqui é
que vamos pegar algum objeto como parâmetro e fazer uma estruturação direta
diretamente daqui. Se salvarmos e atualizarmos, você verá que
as coisas estão como antes Mas agora o código está um pouco mais limpo. Vamos ver na próxima
lição como podemos desenhar alguns elementos aleatórios
para esta carta de jogador.
6. Sinais aleatórios: Agora temos os parâmetros de cor
enviados aos componentes. Isso é muito legal porque
podemos usar essas cores para tornar um componente do jogador
vermelho e o outro azul. Mas o que
ainda não abordamos são esses elementos aleatórios. No final da aula, o que eu quero fazer é
conseguir extrair alguns elementos
aleatórios. Por enquanto,
haverá apenas sequências de caracteres
e as mostraremos nos
componentes, como temos aqui Vamos voltar ao
nosso exemplo aqui. Primeiro, adicionarei o comentário para saber
o que estamos fazendo aqui. E vou definir uma nova
constante, sinais principais. Essa constante será apenas uma matriz simples
contendo algumas strings. Cada string representará um valor possível para os sinais, pedras, papel ou tesoura
com essa matriz Agora posso voltar ao componente
do player aqui,
adicionarei outro comentário, dizendo que estamos gerando um índice aleatório para escolher
algum sinal aleatório. Essa será uma nova constante
chamada índice aleatório. Esse índice aleatório será
uma função matemática. Ele retornará valores aleatórios 0-2 Com esse
índice aleatório criado, agora
podemos criar outra constante chamada sinal aleatório
L aleatório Vamos dar um nome a ele. Esse sinal aleatório será um sinal de índice aleatório. Agora, dado o fato de
eu ter esse sinal aleatório, posso vir aqui e
substituir todo o nome, todo o conteúdo da carta do
jogador por essa matriz. O que significa que
o que vem das escolhas de cores
é isso que geramos aqui Na verdade, eu renomeio
isso para Random Sign. Ok, agora, se atualizarmos, você verá
que o jogador azul
pega papel enquanto o jogador vermelho pega pedra Depois disso, vou atualizar novamente, atualizar novamente e assim por diante Você verá que cada
vez que eu atualizo, um novo sinal aleatório é
escolhido para um determinado jogador
7. Estilos CSS no React: Do jeito que está agora, nosso aplicativo
parece bastante monótono Vamos adicionar
alguns estilos CSS. Para isso, precisarei criar um novo arquivo. Esse arquivo será
chamado de Estilos que CSS. Aqui, vou colar os estilos CSS
necessários. Bem, este não é um
curso sobre CSS. Você pode dar uma
olhada nessas declarações e verá que muitas delas
são bastante autoexplicativas,
como definir um plano de fundo Carlo, como definir um plano de fundo Carlo, alinhar o Agora que
criamos esse arquivo CSS, vamos vinculá-lo ao
nosso arquivo de reação principal aqui. O fato de eu querer
importar uma nova folha de estilo, e essa
vem de estilos que são CSS. Agora, se
atualizarmos, veremos que
já começamos a ter alguns estilos básicos dentro
do nosso aplicativo Temos o plano de fundo, a cor do
texto é diferente, o alinhamento e assim por diante Mas ainda não temos nenhum
estilo aplicado aqui, por exemplo, aos componentes do
player. Para isso, precisarei vincular, por exemplo, a classe player e a classe
container com essas quedas que
temos dentro de nosso aplicativo react Precisarei adicionar
um nome de classe aqui. Eu direi que quero
o nome da classe do jogador. E aqui no outro, quando tivermos o
contêiner principal para o player x, adicionarei um
nome de classe de contêiner. Em condições normais,
isso será apenas classe igual a contêiner
ou classe igual Mas, dado o fato de que a classe
já está funcionando, o trabalho de
reserva em Javascript, precisamos adicionar esse nome de
classe a isso. Vamos voltar e dar algo fresco. Vamos ver agora que temos esses dois elementos
na tela e eles
parecem muito bons. Vou voltar para 100%
do navegador, mas falta uma
coisa. Vamos dar uma outra
olhada no exemplo final. Vou abrir nosso design final. Você verá aqui que
a placa virou. Este está apontando para o lado direito e
este para a esquerda. O que podemos fazer
aqui é entrar
no CSS e adicionar outra regra. Eu direi que quero o segundo filho desse tipo de
jogador seja transformado. A propósito, o que eu fiz
aqui foi um aninhamento CSS nativo. Adicionarei no manual deste curso um link onde
você poderá ler mais sobre ele Mas o que é bom aqui é que,
depois de adicionar essa regra, você verá agora que esse texto
está basicamente invertido Deixe-me abrir outro arquivo. Essa regra que adicionamos aqui, essa transformação de
Scalix menos um vira a carta do
segundo jogador Quando eu adiciono um sinal real lá, ele estará
apontando para o outro lado.
8. Como definir estilos inline: Temos alguns
estilos básicos configurados, mas ainda há espaço pela frente. Por exemplo, não
temos uma cor de fundo para esses itens e também
não temos uma imagem para as placas como pedra,
papel ou tesoura É isso que queremos
fazer nesta lição. Vamos começar com a cor
de fundo. Se dermos uma olhada em como
as coisas estão agora, temos esse parâmetro de cor
que vem no componente. Esse parâmetro de cor pode ser
usado como cor de fundo, porque aqui
teremos vermelho ou azul. Isso é exatamente o que
queremos colocar como
plano de fundo aqui. Para isso, vou usar o estilo
embutido para
definir esse estilo embutido Aqui, estilo igual este recebe como parâmetro
um objeto
Java script completo Eu gostaria de dizer que a cor de fundo
precisa ser exatamente o valor
do parâmetro que
recebemos aqui Será uma cor de fundo e será igual a coloque. Vamos atualizar agora. Vemos que
temos as cartas de jogador com
a cor de fundo pretendida Esse objeto embutido se tornará,
com o tempo, mais complexo Uma boa ideia é vir aqui e extraí-lo como um objeto
separado aqui, nosso estilo embutido correto,
esse estilo embutido será
exatamente o que temos Vou passar esse objeto diretamente
para o estilo embutido As coisas ficarão exatamente
como eram antes, mas temos esse
belo objeto isolado que podemos adicionar
mais valores a ele mais tarde. Agora vamos falar um pouco
sobre as imagens que serão colocadas dentro
das cartas dos jogadores. Em vez de ter aqui uma
pedra ou uma tesoura. Teremos
imagens reais para isso. Eu já preparei
alguns recursos e vou compartilhá-los com você. Agora, acabei de colocar no
meu site os PNGs. Vou abrir essas imagens, você verá que são
exatamente para a pedra, uma para papel e
outra para tesoura Dado o fato de que os PNGs também
podemos ter fundos
transparentes E se dermos uma
olhada melhor no formato da URL,
na verdade, o que temos lá,
é algo assim. Está bem? É o endereço
do site. Mas aqui o que podemos substituir por esse padrão é, na verdade,
por esse sinal aleatório. Por causa desse sinal aleatório, teremos os valores de
pedra, papel ou tesoura Vamos fazer isso. Eu virei e criarei uma nova constante. E essa constante será
igualada a essa URL completa. E depois desse
sinal aleatório, aquele PNG, é muito bom
porque eu posso vir aqui agora e, para
o estilo embutido, adicionar essa imagem de fundo Vamos voltar e atualizar. Veremos agora que temos essas imagens colocadas
em nossos componentes
e, de fato, temos um pouco
de texto sobrando. Então, agora posso deletar isso, pois
não precisamos mais dele. Vamos ver o
exemplo final em ação. Parece muito bom. Por exemplo, cada
vez que eu atualizar, você verá que novos sinais
são desenhados para cada jogador Como nota final,
lembre-se de que temos
aqui os estilos da carta de jogador, temos tudo isso. Temos a repetição do plano de fundo, o tamanho do plano de
fundo, a origem do plano de fundo e assim por diante. E, na verdade, essas são as regras
CSS que nos permitem fazer com que essas imagens tenham uma boa aparência
dentro da carta do jogador. É isso mesmo. Vamos
para a próxima lição. Veremos como adicionar essa bela animação ao
pressionar o botão iniciar o jogo.
9. O gancho useState(): Agora que temos os estilos
embutidos configurados, vamos dar
uma olhada na versão final
do nosso exemplo Nosso jogo começa de
um estado vazio. Você pode ver agora que cada
jogador tem um estado vazio. Nenhum sinal foi
desenhado ainda para um jogador. Somente quando eu pressionar
esse botão de estilo de jogo
, a
animação embaralhada começará e cada jogador
receberá um O que parece
agora é que nossos jogadores, cada um deles, já começam
com um determinado sinal. E a razão para isso é que,
quando começamos com um estilo embutido, definiremos essa imagem de fundo com base no sinal aleatório que foi gerado imediatamente Isso é algo que
queremos mudar. Mas ainda mais, o que queremos
mudar aqui é o fato que eu quero que o jogo
real comece quando eu
pressionar esse botão. Se observarmos o diagrama de fluxo de
dados, basicamente o que
queremos fazer a partir
daqui são as duas partes. Quando pressionamos o botão
Start Gate para enviar um evento para cada componente
do jogador. Vamos ver como podemos fazer isso. Primeiro de tudo, o que
precisamos fazer é mudar
a forma como
as coisas estão aqui. Em vez de ter
esse sinal aleatório gerado toda vez que o
componente é renderizado, queremos extrair o design
em uma variável de estado Portanto, queremos
usar um gancho de estado U. Em condições normais, você
importará um estado U, então você dirá importar o estado
U do react. Mas, dado o fato de não
estarmos usando um servidor web, temos essa configuração
mínima. Precisaremos fazer uma
pequena mudança aqui. E vou importar
o estado U da mesma forma que const e
aplicarei a
instrução de desestruturação em Javascript ao react Mas lembre-se de que, se você
estiver usando um aplicativo recriado, precisará
importá-lo como está aqui. Agora que
importamos o estado U corretamente,
eu virei aqui. No componente player, definirei a
nova variável de estado criada usando esse estado U e ela será sin e set sign. Tudo bem o fato de
começarmos com uma
variável Neal porque queremos aqui iniciar os componentes do
player sem ter
algo selecionado Essa variável de estado definida substituirá esse
sinal aleatório que temos aqui. Ainda mais, podemos extrair
tudo o que está aqui, toda a geração aleatória, queremos
extraí-la em uma função. Devemos ser capazes de
chamar essa função. Quando pressionarmos o botão, substituirei tudo o que temos
aqui por essa função. Se você der uma olhada, essa função pick random sin
contém exatamente as mesmas
linhas que tínhamos antes. Só que, no final,
definimos o sinal aleatório
nessa variável de estado do sinal definido e tudo é encapsulado
em uma boa função. Agora, uma coisa que
precisamos
descobrir é como devemos
fazer para descobrir é como devemos que essa função de
escolha de sinal aleatório
esteja vinculada ao botão. Como podemos fazer de forma
que, quando pressionamos o botão
Iniciar Jogo, essa função seja chamada. Vou deixar isso para
você como lição de casa. Tente fazer isso antes de
começar o próximo vídeo. Acho que existem várias
maneiras de fazer isso, mas se você quiser dar uma dica, tente usar
o usuário fa hook.
10. Eventos de gatilho em componentes filhos wip: Como você conseguiu
encontrar uma solução para isso? Quando pressionamos o
botão Iniciar jogo para enviar eventos para esses componentes A, de forma que novos sinais
aleatórios sejam selecionados. Há várias maneiras de
corrigir esse problema. Vamos ver um plano para
o que queremos fazer. Primeiro, do componente do jogo, passaremos
um novo parâmetro chamado hora de início para
o componente do jogador. Dentro do componente do player, observaremos a hora de início
por meio do gancho de efeito de uso. Quando essa
hora de início for modificada, chamaremos o método
pick random sign. Finalmente, no componente do jogo, atualizaremos a hora de início
quando o botão for pressionado. Vamos ver tudo isso em ação. Primeiro de tudo, vou entrar
no componente do jogo. Aqui vou criar
uma nova variável de estado. Este será chamado de horário de
início, como dissemos. Ele também tem essa função de horário de
início definido. Começará com
o valor nulo, dado o fato de que
você não deseja que
nenhum sinal aleatório seja
detectado no início Agora que esse
horário de início está definido, vou entrar aqui nos dois componentes
do player. Vou enviar o parâmetro da
hora de início. Vou enviá-lo para
o primeiro componente e depois enviá-lo
também para o próximo componente. Esse parâmetro de hora de início em um ponto
precisa ser atualizado. Para isso, vou
criar uma nova função. Essa função será uma
constante chamada start game. Este jogo terá a aparência, então ele definirá a hora de
início na data. Agora, escolheremos a
data e a hora atuais do navegador e as atualizaremos sempre que alguém pressionar o botão
Iniciar o jogo. Por fim, usaremos
a função onclick. Quando alguém pressiona o botão, iniciaremos o jogo Agora, dado o fato de
que sabemos que os componentes do player terão esse novo parâmetro de hora de início, vou
declará-lo aqui e inseri-lo nos parâmetros
do componente Precisaremos observar quando
esse horário de início for modificado. Para isso, precisaremos
importar o gancho de efeito de uso. Vou voltar aqui e aqui
vou chamar também o efeito. Lembre-se de que, se
tivéssemos uma teia normal, você teria que
importá-la daqui Importe-o diretamente do react. Como isso agora foi criado, vamos adicionar o gancho de efeito de uso dentro do
componente player dentro dele. Faremos o seguinte. Verificaremos se
há um horário de início. Lembre-se de que, inicialmente,
esse horário de início é nulo. Se modificarmos a hora de início, chamaremos o sinal de escolha aleatória. Lembre-se de como funciona o efeito de uso. O efeito obtém como parâmetro
uma matriz de valores. Cada vez que esses
valores são alterados, a função incluída no efeito de uso
é acionada. Vamos ver, agora isso em ação. Vou atualizar agora. Inicialmente, não teremos nenhum valor dentro dos componentes
do jogador, mas se pressionarmos o botão de
início do jogo, primeiro
teremos alguns
elementos aleatórios desenhados depois disso. Mais e assim por diante. Basicamente,
descobrimos uma maneira de
começar o jogo pressionando
esse botão. Muito legal. No
próximo capítulo, também adicionarei aquela animação
embaralhada
quando esse botão for pressionado quando esse botão
11. Animações e setInterval: Vamos dar mais uma
olhada no exemplo final. Quando pressionamos o botão, você verá que temos
essa animação que está
sendo executada toda vez que um sinal
aleatório é desenhado. Como podemos implementar
isso em nosso exemplo? Porque, no momento, basta pressionar
o jogo estelar e temos diretamente os elementos
desenhados, mas sem animação. Bem, novamente, aqui, existem
várias maneiras de fazer isso. Também existe uma
solução CSS pura que podemos aplicar. Mas, novamente, seremos a solução que nos
permitirá jogar com alguns mecanismos ou
reagir e ver como
podemos evitar alguns bugs. Vamos tentar.
O que faremos aqui é usar essa função
de intervalo definido. Essa é uma função Javaski, não
é algo que
depende do react Basicamente, o que essa função
faz é
chamá-la e transmitir uma função que será executada a cada atraso. Basicamente, digamos que eu
queira executar algum código a cada 1 segundo, colocarei aqui 1.000 porque é
1 milhão de segundos. E então esse código
será executado cada segundo quando
o ciclo terminar, quando eu não precisar mais que esse código
seja executado, precisarei chamar essa função integral
clara. Então, vamos ver como podemos
implementar isso em nosso exemplo. Em primeiro lugar, precisaremos
saber quantas vezes
a animação foi executada. Vamos dar uma outra olhada quando
vermos que ela dura um tempo e depois para. Isso ocorre porque definimos um
tempo de 20 animações para finalizar. Vou precisar vir
aqui e criar uma nova variável de estado
chamada contador de animação. Este contador de
animação começará do zero. Este mostrará quantas vezes
nossa animação foi executada. E no sinal de escolha aleatória, adicionarei a função set
inteval Queremos que algum código seja executado
a 100 milissegundos, dez vezes por segundo Esse código
é exatamente esse que antes estava diretamente
na raiz da função. Agora ele será movido
na função integral definida, queremos escolher um novo
sinal aleatório em 100 milissegundos. Mas o que queremos fazer é que, em algum momento essa animação pare de
ser executada. Eu virei aqui, vou
verificar se o
contador de animação é maior que 20. Precisaremos limpar a
integral para interromper a animação. E o que eu
transmiti então
na função integral clara
é exatamente essa, as referências que
fiz aqui. Uma última coisa
que precisamos fazer. É também para incrementar em um ponto, esse contador de
animação Cada vez que essa integral for executada, direi que a animação conta aqui. Devemos incrementá-lo com um. Não fique tentado a
fazer algo
assim , porque se
fizermos assim, acabaremos com alguns bugs Lembre-se de que o estado definido, quando executado em valores anteriores, precisaremos chamá-lo assim. Ele será chamado por meio uma função que
terá acesso
ao valor anterior e
incrementaremos esse valor mais um Ok, dock, agora vamos executá-lo. Vamos pressionar o botão de
início do jogo. Você verá que temos a
animação em funcionamento, o que é muito legal. Vou recarregar a
página no momento. Se você jogar
com este exemplo, verá que há dois bugs na próxima lição
antes de você realmente começar. Em primeiro lugar, tente
descobrir quais são os insetos, os
dois, e
experimente. Tente consertá-los. Nos vemos na próxima aula, então.
12. Como adicionar useRef() e limpar useEffect(): Terminamos a última aula
com alguns bugs em nosso código. Deixei para você como lição de casa, a ideia de tentar encontrar
esses bugs e consertá-los. Primeiro de tudo, vamos
ver o que são. Há dois
bugs principais em nosso código, e eu fiz essa imagem
para eles mostrarem. Em primeiro lugar, quando
começarmos a animação, você verá que essa
animação é executada para sempre. Não para depois de 20 corridas, mesmo que tenhamos aqui uma condição muito clara de que, se um encontro for maior que
20, precisamos parar. Esse é o primeiro bug
e talvez o mais importante também se
iniciarmos a animação. E depois que eu avanço, pressiono esse botão, você verá que a animação
começa a ficar estranha. Vai muito rápido, que também deveria
, não para. Finalmente, há
também um terceiro bug que é o mais fácil de corrigir. Você verá que, se entrarmos agora na imagem do arquivo, você verá que temos
esse nulo, esse PNG, o fato de que nosso arquivo está
tentando recuperar esse
nulo, esse Vamos começar com essa fruta
barata. Vamos primeiro, pelo menos, tentar corrigir esse erro que
aparece no console. A razão para isso é, na verdade essa linha, a imagem de fundo. O que fazemos aqui é
tentar
recuperar a imagem do site de porcaria
do JS, e temos aqui a placa Inicialmente, você pode ver que esse sinal começa
com o valor nulo Essa é a razão pela qual
recebemos esse erro, porque aqui estamos tentando recuperar os ativos, seja o que for Depois disso, aquele PNG, uma solução
bastante fácil
para isso será testar se o sinal existe. Se o sinal existir, tente buscar a imagem Caso contrário, não faça nada, basta recuperar aqui
uma string vazia Vamos atualizar e você verá agora que o erro não está
presente no console Esse foi o primeiro bug. Vamos agora passar para o
mais complexo. O fato de que, quando
iniciamos a animação, não
recebemos nenhum erro, mas a animação é executada para sempre, mesmo que
haja essa condição aqui. A razão pela qual isso
acontece é porque
essa parte é como se o estado definido no react
não fosse síncrono Quando tentarmos
executar essa condição, ela ainda não será atualizada. Por exemplo, se eu consolar
aqui um encontro e
atualizo e inicio o jogo, você verá que
é zero para sempre. E o motivo é
porque ele não teve a
chance de realmente
fazer a atualização completa. Uma maneira de corrigir isso é
agrupar tudo dentro
da função de contador setanym e usar esse valor anterior
como nossa referência Por exemplo, fiz no
manual do curso, fiz esse exemplo O que podemos fazer é fazer aqui uma embalagem grande e colocar todo o código dentro
do contador de estandes. E saberemos com certeza agora que o valor do estado está atualizado
e tem o valor correto. Mas isso não é ótimo porque na verdade, existe a integral da função pick
rand, um estado definido, é
um pouco demais. Outra coisa que podemos tentar fazer é usar referências. É ótimo trabalhar
com referências e
usá-las no react. Os formulários também são ótimos
para armazenar valores que são mantidos entre as renderizações, mas que não precisam ser mostrados
na UY real O que vou precisar fazer aqui
é substituir isso, qualquer contador por
qualquer contrarreferência. Dado o fato de que
queremos usar este trabalho, porque F é na verdade
uma referência, precisarei importá-lo
do valor real da referência mantido
no campo atual
da referência. O que precisamos fazer aqui é,
quando iniciamos a animação, pegar esse contador e
dizer que a corrente
é igual Depois disso, em vez de usar a variável de estado definida, eu vou. Volte para a referência e diga que eu quero
aumentá-la em um. Finalmente, aqui eu posso simplesmente usar essa em vez da
antiga variável de estado. Vamos ver no que vai dar. Vou voltar a atualizar depois disso. Se pressionarmos Iniciar jogo. Agora, a animação está parando
após 20 iterações. Vamos atualizar novamente para iniciar o jogo. E a animação agora é interrompida após 20
execuções, o que é ótimo. Corrigimos outro bug. Finalmente, vamos
resolver o último bug. Vou voltar
ao exemplo, agora vou começar a pressionar muito rápido o
botão de início do jogo. Você verá que a animação
está indo muito rápido, que deveria. Na verdade,
existem duas maneiras. Existem várias maneiras, mas duas
maneiras principais de corrigir isso. Uma maneira de fazer isso é usar
outra variável de estado e desativar esse botão enquanto a animação é
executada, o que é normal. Mas vamos entrar em outro tópico, nós reagimos e essa é a função de limpeza de
efeitos de uso. Basicamente, o que acontece
quando pressionamos muito rápido, esse botão, o
parâmetro da hora de início, é modificado. Chamamos essa
função de sinal aleatório algumas vezes. Na verdade, estamos fazendo vários intervalos que correm e mudam nosso signo muito rapidamente Essa é a razão pela qual a
animação age assim. Uma coisa que podemos fazer é
usar a
função de efeito de limpeza. Effect tem uma função
que só precisamos
retornar uma determinada função, como. Então essa função,
que eu tenho aqui, será chamada toda vez que
um novo efeito de uso for executado. É assim que
garantimos que
estamos eliminando todos os
efeitos de uma corrida anterior. Na verdade, o que queremos fazer aqui é limpar essa integral. Basicamente, queremos
chamar isso também aqui. Deveríamos ter
algo assim. Mas você vê que a integral real é feita nesta função
e precisamos dela aqui. Outra coisa
que podemos fazer é criar uma segunda
referência, essa, vou apenas copiar
essa função aqui, e vou dizer minha
integral O aqui. Em vez de criar apenas uma variável
local que
não será exposta ao escopo do efeito de
uso, o que posso fazer é pegar essa referência. Eu direi que essa
corrente é igual
a uma integral definida Eu vou sair daqui. Mas agora eu também
posso sair daqui. Na verdade, como essa
é apenas uma função de linha, posso substituir tudo por apenas essa para torná-la
um pouco mais bonita Agora vamos executar novamente o exemplo. Você verá que cada vez eu pressiono o botão agora é muito
rápido, mas ainda assim a animação
funciona como deveria. Cada vez que pressiono o botão
novamente, este é executado e o intervalo atual
é apagado Foi assim que conseguimos
consertar todos os nossos latidos. Vamos ver na próxima
lição como podemos usar a API de contexto A para comunicar valores de
um componente para outro.
13. Provedores de contexto no React: Agora que nosso aplicativo
está de volta gratuito, vamos passar para talvez
a última etapa antes de decidir o vencedor do jogo e concluir
o aplicativo Esta parte diz respeito à forma como nos
comunicamos entre os componentes. Vamos dar uma olhada no
nosso exemplo final. Temos essas duas
cartas de jogador dentro delas. Alguns sinais aleatórios são desenhados. Por outro lado, está
o componente Resualboard, aquele que temos aqui
que deve saber o que cada jogador selecionou para decidir
quem venceu o Podemos fazer isso passando
adereços de um
componente para outro, mas nesse caso
será um pouco mais complicado Nós podemos fazer isso, mas
será mais complicado. Outra desvantagem dessa
abordagem é o fato acabarmos perfurando
demais adereços É assim que as coisas são chamadas
quando passamos muitos componentes de
um componente para outro. Outra maneira de corrigir isso
e também jogar com algum recurso do react é
usando o contexto. Vamos ver como isso parece. O que queremos fazer é
configurar um contexto de reação. Depois que cada jogador
escolher um sinal aleatório, eles comunicarão
ao contexto qual foi
o sinal escolhido. Depois disso, nosso componente
resultusboard captará os dois sinais
do contexto Ele decidirá quem venceu o jogo. Você pode pensar no contexto de
reação como um armazenamento de dados geral
para o aplicativo. Vou colocar um link no
manual deste curso para um vídeo que fiz há
algum tempo explicando com mais detalhes
como o contexto do ato funciona Mas, basicamente, você
pode imaginá-lo
assim como um
local geral onde podemos colocar dados que podem ser acessados por cada componente de
um determinado aplicativo. Ao final das duas lições, esta lição e a próxima,
queremos terminar com
um queremos terminar com componente do quadro de resultados
que se parece com,
então, ele sabe o que o jogador
vermelho escolheu e também o que o jogador
azul escolheu. Vamos ver como podemos traduzir toda essa
conversa em código. A primeira coisa que
precisarei fazer é criar um
contexto para o nosso jogo. Este será nomeado
exatamente da mesma forma que contexto do jogo, contexto do jogo é igual ao contexto
de criação Essa criação de contexto é uma
função que vem do react. Se apenas criarmos um contexto, não
podemos fazer muita coisa
com ele porque também
precisamos criar um provedor de
contexto aqui. Vou criar um provedor de
contexto de jogo que é feito com base nesse
contexto que criamos aqui. Podemos pegar esse provedor que acabamos de criar e
passá-lo para nosso aplicativo e incluir todo o jogo no provedor de contexto do
jogo. Podemos ler em cada um de
seus subcomponentes o que colocamos no
contexto do jogo neste momento Se eu salvar o
arquivo e
atualizá-lo, você verá que temos alguns
problemas com o que aconteceu aqui A razão pela qual a
LUI desapareceu é que agora estamos renderizando
o provedor de contexto do jogo E, de fato, estamos falecendo
quando crianças. Estamos transmitindo o jogo, mas aqui, no provedor
real, não
estamos renderizando
essas crianças Então, precisaremos
adicionar um novo nome de propriedade. Crianças. Na verdade, essa
é uma propriedade padrão para qualquer componente de reação. Vamos atualizá-lo
e você verá que agora as coisas parecem como antes Só que nosso jogo
agora está incluído
neste provedor. Uma coisa legal que
podemos fazer
é adicionar um estado
para o provedor. E esse estado
será transmitido a todos os componentes
desses provedores. Vamos ver como podemos fazer isso. Eu virei aqui e adicionarei o estado do provedor de
jogos que
precisamos conter em nosso estado. Se pensarmos bem,
serão os sinais do jogador, o que o
jogador vermelho selecionou. Além disso, o que o jogador
azul selecionou? Com isso,
agora eu posso vir aqui e passar esses valores para o player
senes e para a função Seta Vou passá-lo
para o provedor. Neste ponto, as coisas
ficarão como antes, não
haverá
erros no console, apenas poderemos
ler esses valores em qualquer subcomponente
do provedor de contexto Veremos na próxima lição como atualizar esses valores
e como lê-los.
14. O gancho useContext(): No final da lição
anterior, conseguimos criar e
configurar esse contexto de jogo. Encapsulamos nosso jogo
neste provedor de contexto de jogo. Como lembrete, deixe-me mostrar o que estamos
tentando fazer aqui Estamos tentando ler os
sinais que foram captados por essas duas cartas de jogadores e colocar os sinais
no contexto real. Depois disso, podemos usar no componente
do quadro de resultados, os sinais, para que possamos
decidir quem venceu o jogo. O objetivo desta
lição é ler esses elementos e também
defini-los quando eles são selecionados. Vamos começar lendo o contexto do
jogo em um componente. Vou entrar no componente do
player. Aqui, escreverei o seguinte contexto,
contexto, contexto do jogo. Isso significa que estamos
usando outro gancho. Precisaremos
importá-lo daqui. Esse gancho fornece acesso
a um determinado contexto, no nosso caso, é o único contexto que temos, o contexto do jogo. Como lembrete, temos essas duas variáveis de estado
definidas no contexto, os
valores vermelho e azul para cada jogador Deixe-me registrar este. Vou registrar o contexto. Vamos ver se, de fato, temos esses dois elementos lá
enquanto usamos o console. E você pode ver aqui o
que obtemos
desse objeto consologista e
o que ele retorna em primeiro lugar,
os sinais do jogador que
configuramos e também a função
set para
essa variável de estado Isso é muito legal
porque podemos entrar
na função de escolha de sinal aleatório
e definir esses dois valores, o vermelho e o azul. Mas antes de ir para lá, podemos melhorar um pouco essa linha. Em vez de escrever apenas isso, posso usar a declaração
estruturante. Junto com o contexto do jogo, posso dizer que
quero recuperar
a função definida e
os sinais do jogador Dado o fato de que agora temos esse método de definir sinais de jogadores, eu deveria vir aqui e
ligar e dizer, ok, definir sinais de jogadores. Mas agora eu escrevi isso aqui
no if, quando o elemento final é desenhado. Agora a pergunta é: o que
devo escrever aqui? E lembre-se de que aqui
estamos tentando atualizar um elemento. O que estamos tentando
fazer aqui é atualizar um
objeto em um estado de reação. Porque,
voltando ao provedor, você verá que esse
é um objeto real. A maneira de fazer isso é
usar também um valor anterior. O que faremos aqui é
espalhar todos os elementos que já temos no objeto e simplesmente
sobrescrever o que precisamos, no nosso caso, substituir
a cor do jogador e
o
sinal aleatório que foi selecionado Com isso em mente,
vamos voltar agora ao quadro
do Zulus e ver o que
temos no contexto Eu vou aqui, vou
adicionar essas duas linhas. Em primeiro lugar, estou extraindo os sinais
do jogador do contexto Depois disso, adiciono mais um
nível de estruturação, e este está extraindo exatamente os valores de
azul e vermelho Deixe-me registrar os dois. Eu vou dizer azul. Vamos atualizar e agora
vamos começar o jogo. Você verá que partimos
dos valores nulos e
terminamos com o papel e a pedra
exatamente o que temos aqui Isso é muito legal porque
agora podemos completar esse componente de caixa resoluta
mostrando o que cada
jogador desenhou Basicamente, essa parte daqui. Vou remover o console
porque não precisamos dele. Em primeiro lugar, devemos verificar
se os dois elementos estão definidos, caso um
desses elementos azuis ou vermelhos não esteja definido, então ainda não devemos retornar nenhum resultado exatamente como
temos neste momento. Depois disso, se os dois
elementos estiverem definidos, podemos escrever essa linha. Deixe-me atualizar. Vou
começar o jogo inicialmente, não
há resultados. E depois disso, ele me
dirá, ok, esse jogador azul
selecionou rocha, esse jogador vermelho
selecionou rock. E é exatamente o que também
temos aqui. Com isso, abordamos
um exemplo de como
podemos usar o
contexto A para enviar valores de um
componente para outro maneira fácil, sem precisar transmitir
muitas propriedades. Vamos ver a peça
final que
falta no quebra-cabeça e ver como
decidiremos o vencedor. Então, como podemos
escrever algo assim? O vencedor é o
jogador azul ou o jogador vermelho.
15. Decidir o vencedor do jogo: A peça final
do quebra-cabeça será
determinar quem venceu o
jogo e mostrar o vencedor. A propósito, nesta lição,
não apresentaremos nenhuma
novidade de reação, é apenas Javas puro Determinaremos o vencedor
no quadro de resultados. Para isso, vou criar
uma nova função. Este será chamado de Win. Ele nos fornecerá parâmetros, os
valores de vermelho e azul para os jogadores. Depois de criar essa função, também
precisaremos chamá-la de
A no x retornado do componente. Usaremos o
seguinte algoritmo. Não. Para determinar o vencedor, verificaremos se há empate, se os símbolos são iguais. Depois disso,
verificaremos se o vermelho vence. Se não houver empate e o vermelho
também não vencer, é seguro presumir que
o jogador azul vence. Vamos primeiro verificar
o que é simples. Para verificar
se temos um empate, precisamos apenas verificar
se vermelho é igual Se quisermos, essa corda para
verificar se o jogador vermelho
é, é um pouco mais complicada,
parecerá Então, listamos aqui as três principais condições
sob as quais o vermelho vencerá. Essas são as combinações
possíveis que farão do jogador
vermelho um vencedor. Se tivermos alguma
dessas condições, retornaremos essa string. Finalmente, o mais simples em que nem
precisaremos verificar nada porque já
verificamos se temos um vermelho é esse. O player azul simplesmente retornará a string se isso não for
verdade ou não for verdade. Vamos ver agora tudo isso
em ação. Vou refrescar. Vou começar o jogo e,
finalmente, no final, ele me mostrará quem venceu o
jogo e, de fato, está correto, porque o papel vence o rock Vamos fazer outra rodada. Aqui é o mesmo. Pedra supera tesoura.
Sim, é isso. É assim que escrevemos
a função para verificar o vencedor. A propósito, se você acha que
isso é um pouco demais, eu adicionei no manual
também a refatoração da disfunção,
parece que sim, na minha opinião, na
verdade é um pouco mais
compacto, verdade é um pouco mais
compacto Mas acho que é um
pouco mais difícil de ler. Não sei,
o que quer que funcione, você pode escolher e
tudo ficará bem.
16. Projeto do curso: Agora que aprendemos
todas essas coisas novas, é hora de colocá-las em ação. Queremos adicionar alguns novos
recursos ao nosso jogo. Em primeiro lugar, queremos ter
um painel de controle de pontuação aqui. Além disso, cada jogador deve
ter seu próprio nome. E esses nomes são editáveis. Vamos ver a versão final
do Home Work em ação. Vou pressionar o
botão Star Game após o término de um jogo, você verá que agora
temos um contador aqui. O azul tem uma vitória e o
vermelho tem zero vitórias. E também podemos redefinir
a pontuação para zero. E pelo fato de
termos adicionado esses nomes, agora também
posso editar
e dizer, ok, quero que meu novo nome seja Daniel e isso
será atualizado aqui. E em vez de CPU,
eu quero jogar,
digamos, contra a IA e o nome também
será atualizado lá. Como regra geral, primeiro
tente concluir
tudo isso sozinho
e, se não funcionar, assista à próxima sessão
deste vídeo. compartilharei com vocês
algumas dicas sobre como criar final, compartilharei com vocês
algumas dicas sobre como criar
esses novos recursos. Se você quiser, você também pode conferir
o final da lição onde você pode ver o código que nos permite
criar tudo isso A partir deste momento,
compartilharei com vocês algumas dicas sobre como
criar esses novos recursos. Portanto, lembre-se de que,
a partir de agora, teremos alguns spoilers Basta acessar esta
seção somente se você tiver tentado inicialmente jogar sozinho. Em primeiro lugar, vou começar com esse recurso adicionando
nomes aos jogadores. Acho que esse é um
pouco mais fácil de implementar. Quase todas as
mudanças precisam ser feitas aqui no componente
player. A primeira coisa que farei aqui é adicionar um parâmetro do player. Esse parâmetro virá
diretamente do jogo. Depois disso, com esse parâmetro
do player,
criarei uma variável de estado
do nome do jogador. Quando clicarmos nesse nome, usarei essa janela. O prompt de janela é um
recurso do Javaski, não uma reação, que nos permite criar
janelas como esta, onde você pode inserir
o novo nome, as coisas que você
viu Depois de lermos o novo
valor no prompt do Windows, devemos atualizar o estado. E com isso, devemos
concluir o novo recurso. A propósito, também há um bônus aqui em que podemos tentar
extrair tudo isso em
um componente de nome de jogador, incluindo
apenas o jogador, esse componente de nome de jogador. Passando agora para o segundo
recurso, a parte do placar. Essa parte está aqui. Tudo deve entrar
aqui neste quadro. Aqui, o
placar deve estar. Devemos adicionar como
layout um botão A. Isso pode ser um título ou
algo parecido, e também um parágrafo
com esse texto. Enquanto adicionamos este, complicaremos um pouco o estado do componente
Resulusborg O que precisaremos fazer aqui é
adicionar vários
valores de estado para a pontuação criada, pontuação azul e também
a do vencedor atual, ou também podemos adicionar um objeto
centralizado, dobramos o estado em
apenas um único Outra coisa que
precisaremos fazer é usar o gancho de efeito de uso
para substituir este. Temos aqui o vencedor da escolha, visto que quando
escolhermos o vencedor, também
atualizaremos a
pontuação e a pontuação, que também é uma variável de estado. Vamos acabar em um
loop infinito de renderização Re. Basicamente, precisaremos
removê-lo daqui e colocá-lo em um gancho de efeito de uso que
monitorará quando novos valores de azul
e vermelho aparecerem. Ok, uma última coisa
que você deve ter em
mente é que, ao
atualizar a pontuação, você deve sempre atualizar a pontuação com base
no valor anterior. Devemos ter
algo assim
no estado anterior e
anterior mais um. Por fim, você pode extrair tudo o que
temos aqui em um componente do placar depois tentar criar esses recursos por conta própria, também conferir a solução
e ver como funcionou, comparar um com o outro E também não se debruce apenas
sobre esses recursos. Deixe sua imaginação correr solta e tente adicionar todos os tipos
de recursos aqui. Mas uma coisa muito importante
é aproveitar o processo. Divirta-se e fique feliz programando.
17. Conclusão: Conseguimos muito com nosso exemplo, começando
do zero. Construímos um minijogo de reação totalmente
funcional. Embora tenhamos feito isso, também
vimos coisas
como inicializar um
projeto de reação do zero Mas também como podemos
definir componentes e adereços. Também vimos como
usar o estado,
o estado de reação para atualizar
os componentes UY. Mas também é muito importante
como podemos atualizar um estado com base no valor
anterior do estado. futuro,
vimos como
usar os dois estilos CSS básicos,
mas também como usar estilos embutidos
para fazer com que nossos
aplicativos tenham uma ótima aparência Também vimos como
usar o gancho de efeito de uso para monitorar os valores
e acionar atualizações. Também é muito
importante como usar
a função
de limpeza do efeito de uso para
evitar bugs como complemento
às variáveis de estado. Vimos como usar
o F para manter valores
persistentes entre as
renderizações Re e também como
configurar coisas como provedores de
contexto para compartilhar dados entre
componentes e muito mais Espero que este curso tenha
sido útil para você e que você tenha
aprendido coisas novas. Parabéns por
concluir o curso e obrigado pelo seu tempo. Lembre-se de que você também pode conferir o manual
principal deste curso E se você tiver dúvidas, não
hesite em me
escrever um e-mail Daniel Gongcrafto daqui para frente Lembre-se, de tempos
em tempos, de que você também
pode verificar meu
site, onde eu publico
regularmente
novos artigos para melhorar sua
arte de webcoding Desejo a vocês tudo de bom e
continuem programando, amigos. Tchau tchau.