Tiffany White Blocked Unblock Seguir Seguindo 10 de janeiro
Eu amo o CodeSandbox . Ele praticamente substituiu o CodePen por mim, a menos que eu esteja mexendo em projetos front-end CSS ou freeCodeCamp.
Eu gosto de passar pelas caixas de areia e escolher diferentes para olhar, desmontar e descobrir como elas funcionam.
Enquanto eu fazia o React Tutorial for Beginners de Kent C. Dodds no Egghead.io , decidi procurar por sandboxes correlacionados com o curso, pois eu estava usando o Codesandbox para construir o cronômetro que estávamos construindo naquele curso.
Eu encontrei uma caixa de areia que eu bifurfei e encontrei para ser buggy.
Por que o cronômetro não funcionou? Olhando para o código por alguns segundos, vi alguns problemas óbvios imediatamente.
Aqui está um exemplo do cronômetro sendo quebrado:
Correção 1
A primeira coisa que notei foi na linha 7:
Date.now()
precisa de parênteses. Date
é um construtor de objetos com .now()
sendo um método. Quando clicamos no botão de início, o React não sabe o que fazer aqui; nós não estamos definindo o estado de lapse
para ser um número, o que esperamos. Adicionando os parênteses, obtemos o botão iniciar para trabalhar. Não mais NaNms
.
Mas agora temos outro problema: o temporizador não pára .
Eu também removi o console.log(Math.random());
porque eu senti que era desnecessário.
Correção de Problemas 2: Fazendo o cronômetro parar e limpar
Cada vez que o botão é clicado, definimos o estado para running
ou lapse
. O cronômetro é executado quando clicamos em start
mas clicar em stop
ou clear
parece não funcionar. Como podemos consertar isso?
Podemos criar uma função de atualização do temporizador que aceita o estado atual. Podemos fazer isso usando APIs nativas do DOM, como setInterval()
e clearInterval()
. Podemos executar a lógica condicional para ver se o cronômetro está em execução:
e use Date.now()
para obter o registro de data e hora em ms e designar uma variável startTime
para comparar o horário atual com o tempo decorrido. Quando clicamos no botão Iniciar, ele define o startTime
como o timestamp atual. Também precisamos retornar um novo estado, pois o estado não é mutável.
Ok, isso funciona parcialmente . Mas, como você pode ver abaixo, se eu clicar em clear
enquanto o temporizador do cronômetro estiver em execução, ele não apagará o cronômetro e também não permitirá que eu pare o cronômetro.
Como consertamos esse bug em particular?
Se olharmos para o código anterior, podemos ver que estamos usando clearInterval()
para redefinir o cronômetro. Em nossa iteração atual, nosso método handleOnClear
é apenas definir o estado sem limpar o estado anterior.
Podemos corrigir isso adicionando clearInterval()
e passando a função timer para o método handleOnClear
para limpar o estado.
Isso nos dará os resultados que queremos.
Problema potencial?
Há um vazamento de memória nessa iteração específica. O cronômetro será executado até que seja explicitamente interrompido no DOM. Podemos usar um método de ciclo de vida de Reação para interromper todos os processos no DOM quando esse componente é montado ou desmontado.
Para isso, podemos usar componentWillUnmount
para dizer ao React para desmontar o componente assim que ele for renderizado.
Pensamentos e Conclusões
Acho muito mais divertido consertar os erros de outras pessoas do que o meu. Este foi um exercício divertido e eu planejo fazer isso mais regularmente e blogar sobre isso.
Este cronômetro é um componente simples e estúpido, mas se você está apenas arranhando a superfície do React como eu estou, estou certo de que cavar em algo como este cronômetro e descobrir como ele funciona é um excelente exercício e uso do tempo.