da2k / curso-reactjs-ninja

916 stars 323 forks source link

M1#A48 - formas de fazer “bind” do this em eventos #31

Closed hgtpcastro closed 7 years ago

hgtpcastro commented 7 years ago

Fala @fdaciuk, beleza?

Fiquei com dúvida sobre a diferença entre os binds do método handleSearch e getRepos. Porque não precisamos fazer o bind no constructor para o getRepos?

Porque o método getRepos é executado logo que a pagina é carregada e o método handleSearch não?

Se eu remover a arrow function ( return (e) => { ) do método getRepos, o que muda no bind deste método?

Estou no começo o curso agora e tendo o meu primeiro contato com o React, então desculpe se estou escrevendo alguma bobagem.....

fdaciuk commented 7 years ago

Opa @hgtpcastro! Essa sua dúvida não é específica sobre React, mas sim sobre um comportamento do JavaScript. Vou te explicar o ponto do problema e o porquê de usar o bind =)

O this no JavaScript não funciona como em outras linguagens. Normalmente, em linguagens que utilizam um paradigma orientado a objetos, o this dentro de uma classe é a representação do objeto que foi criado utilizando aquela classe.

Em JavaScript, o this dentro de uma função depende de como e onde a função ou método é invocado.

Para entender esse assunto, leia esse artigo antes de continuar a leitura aqui, vai deixar as coisas mais claras.


Se você leu o artigo acima, viu que o this muda dependendo da forma que você invoca a função, e você viu também que pode "injetar" quem você quer que seja o this dentro de uma função, certo? Esse é o motivo de usarmos o bind no constructor.

Quando você cria uma class, e adiciona alguns métodos a ela, se você invocar qualquer método de dentro da class, o this vai fazer referência a essa class.

Mas quando você usa qualquer um desses métodos como callback de um evento JavaScript, o this dentro dessa função passa a ser a representação do elemento do DOM que o evento foi adicionado.

Ou seja: o método handleSearch é usado é usado no evento onKeyUp do input de busca. Logo, o this dentro desse método vai fazer referência ao input, a menos que, ao criar a função, nós dissermos explicitamente quem deve ser o this. E fazemos isso usando o bind dentro do construtor, sobrescrevendo o valor atual do método por ele mesmo, mas "forçando" que o this seja sempre a classe.

Isso funciona porque o constructor é executado quando a classe é criada. Nesse momento, os métodos da classe já existem, e podem ser sobrescritos, como qualquer método de objeto em JavaScript.

Então, em resumo, o bind é para que você tenha a garantia que, ao usar o this dentro de uma função, ele vai fazer referência à classe, não ao elemento do DOM, que não vai ter o método setState, que é o que precisaremos utilizar para atualizar o componente =)


No caso do método getRepos, dentro desse método nós não utilizamos o this. Esse método é invocado quando o método render é executado. A primeira invocação desse método retorna uma nova função. Como essa função retorna uma arrow function, não precisamos fazer o bind, pois arrow functions tem o this léxico, o que significa que, o this usado dentro de qualquer arrow function vai ser o mesmo this que já estava no escopo da função anterior.

Como invocamos a função getRepos no render, e o render faz parte da classe, então o this dentro de getRepos já é a classe. Apesar da função retornada ser passada para um evento, o uso da arrow function já faz o trabalho de usar o this correto, sem ter a necessidade de fazer o bind dessa função.

Deu pra entender? =)

hgtpcastro commented 7 years ago

Grande, @fdaciuk

Deu para entender sim, muito bem explicado.

Obrigado pela atenção

fdaciuk commented 7 years ago

Show @hgtpcastro! Qualquer dúvida, só avisar =)