Meu último bugfix: ou, como eu fui espeleologia no código de outra pessoa

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.