da2k / curso-reactjs-ninja

915 stars 322 forks source link

M1#A22 - Erro ao criar uma variável dentro do constructor #565

Closed marisbispo closed 3 years ago

marisbispo commented 3 years ago

Boa tarde, tudo bom?

Na aula, você cria uma variável dentro do constructor, assim:

class Timer extends Component{
    constructor(){
        super()
        this.state ={
            time:0
        }

        this.timer;
    }

Quando eu faço isso, da o seguinte erro no meu codigo:

"Failed to compile src\timer.js Line 10:9: Expected an assignment or function call and instead saw an expression no-unused-expressions

Search for the keywords to learn more about each error."

Quando eu tiro esse "this.timer" dentro do constructor, ele nao dá erro algum.

Queria entender o porque! E além disso, se eu nao poderia criar uma variável com let, exemplo:

let timer;

e ai fazer o clearInterval usando esse variável!

Obrigada!

Segue o meu codigo com o erro:

import React, {Component} from 'react'

class Timer extends Component{
    constructor(){
        super()
        this.state ={
            time:0
        }

        this.timer;
    }

    componentDidMount(){
        this.timer = setInterval(()=> {
            this.setState({
                time: this.state.time+1
            })
        }, 1000)
    }

    componentWillUnmount(){
        clearInterval(this.timer)
    }

    render(){
        return(
            <div>Timer:  {this.state.time}</div>
        )
    }
}

export default Timer;

@fdaciuk

fdaciuk commented 3 years ago

Oi @marisbispo! Essa mensagem não é um erro da linguagem, e sim do ES Lint, por isso ela não é exibida no código que eu mostro. Você deve estar usando o Create React App né? Como ele já vem com o linter configurado, ele acaba exibindo algumas mensagens a mais, mas que tem mais a ver com estilo de código mesmo.

No caso, remover o this.timer do constructor não vai ter diferença prática, o código vai funcionar igual sem problemas, então pode remover =)

Sobre criar a variável com let fora da classe, não recomendo pelo seguinte motivo: uma classe serve para construir objetos. Cada objeto que você constrói usando uma classe é uma instância diferente desse objeto em memória.

No caso do React, cada vez que você chamar <Timer />, você está chamando uma instância diferente do componente Timer.

Se você tiver 3 timers no seu projeto, são 3 objetos complemente diferentes.

E se todos esses objetos dependerem da mesma variável timer, que vai ser criada fora da classe, o que vai acontecer é que o ID do setInterval que vai ser atribuído para a variável timer vai ser o ID da chamada do último <Timer />.

Logo, quando você mandar parar qualquer um dos 3 timers, apenas o último é que vai parar. Todos os outros irão continuar rodando, já que eles compartilham da mesma variável.

Quando você cria o timer "pendurado" no this, o this dentro da classe é a instância do objeto que está sendo criado, logo, ao chamar 3 vezes o <Timer />, cada um deles vai ter seu próprio this.timer, e os timers poderão iniciar e parar de forma isolada :)

Deu pra entender a ideia? =)

marisbispo commented 3 years ago

Excelente! Deu sim! Mto obrigada

fdaciuk commented 3 years ago

Qualquer dúvida, só avisar! =)