da2k / curso-reactjs-ninja

916 stars 323 forks source link

Pq meu this esta undefined ? #75

Closed llmdev closed 6 years ago

llmdev commented 6 years ago

Mano, desculpa ficar abrindo as issues, mas sao duvidas que aparecem...

Meu this aqui esta retornando undefined ? Estou usando arrow function, nao entendi pq ele se perdeo

https://github.com/llmdev/curso-react/blob/master/src/App.js#L50

@fdaciuk

gabrielferreiraa commented 6 years ago

Você precisa fazer bind do this. No constructor ou no momento de usar a função.

No constructor:

this.getRepos = this.getRepos.bind(this)

OU

Na chamada da função:

[...]
getRepos={this.getRepos.bind(this)}
[...]
llmdev commented 6 years ago

Hmm entendi mas assim queria entender. Eu passo minha função getRepos() de pai para filho.... Aonde eu estar para executar () ele pega o escopo local do componente ? Se vc ver em meus códigos eu executo () ele dentro do componente search, se eu executar ele no componente app ele entende o this do escopo de app

gabrielferreiraa commented 6 years ago

Ai o mestre saberia explicar com mais excelência @fdaciuk hahahahha

fdaciuk commented 6 years ago

Oi @llmdev! Sem problemas cara, se tiver dúvidas é pra perguntar mesmo =) @gabrielferreiraa, obrigado pela ajuda =)

Então, vamos lá: basicamente o que acontece é que o getRepos é um método da class App. O this sempre pode mudar seu contexto, dependendo de como a função é executada.

Ao fazer o que o @gabrielferreiraa comentou, fazendo o bind da função no constructor, você garante que, ao executar aquela função, o this vai ser sempre o this da class, ele não vai ser injetado.

Quando usamos componentes de função, ou quando passamos alguma função para um evento no React, ele faz o this ser undefined. Em JS puro, apenas executando o método em outra função não invalidaria o this, a menos que você passasse esse método para um evento. Nesse caso, o this seria o elemento do DOM que está executando o evento.

Por isso o seu this é sempre undefined.

Se você executar o getRepos antes de passar ele para o AppContainer, você não terá esse problema ;)

llmdev commented 6 years ago

@fdaciuk Obrigado pela explicação mano, entendi legal..

Tem algum link para eu verificar os melhores padrões dentro do react ?

se eu executar o getRepos() antes de passar para o appContainer e não colocar o bind no constructor isso pode ser um anti pattern ?

obrigado.

fdaciuk commented 6 years ago

O ideal é: faça bind para qualquer método que não faça parte do lifecycle do React, ou principalmente quando você for passar o método para um evento.

No exemplo que eu mostrei funciona certinho pq eu executo o método getRepos no App, e o retorno desse método é uma arrow function, que vai manter o escopo léxico, ou seja: o this, no momento em que essa função foi criada, vai ser o this dentro dela ;)

fdaciuk commented 6 years ago

Mais pra frente no curso eu mostro outra forma de criar esses métodos, como propriedade da class (no módulo 03) =)