Hej,
mam jedno pytanie dotyczące działania this w Reacie.
Przeglądam sobie kurs Samuraja Programowania z Udemy i w jednym z pierwszych filmów napisał przykładowy skrypt, który polega na tym, że po kliknięciu na przycisk "pokaż" pojawi nam się na stronie tekst, jeżeli klikniemy ponownie, to zostanie ukryty. Poniżej umieszczam link do skryptu:
https://jsfiddle.net/db7f96Le/
Chciałbym się zapytać, dlaczego było konieczne zbindowanie metody handleMessageButton
w konstruktorze? Znaczy się wiem, że zrobiono to ponieważ zostało zgubione wiązanie this
w momencie wywołania metody po kliknięciu na przycisk, za pomocą onClick
a:
<button onClick={this.handleMessageButton}>
{this.state.messageIsActive ? 'Ukryj' : 'Pokaż'}
</button>
Tylko dlaczego to zostało zgubione? Przecież metoda handleMessageButton znajduje się w klasie Message, więc chyba this użyte w tej metodzie powinno chyba i tak wskazywać na obiekt, który jest instancją klasy Message?
Zacząłem coś teraz czytać na necie i przeczytałem, że w React (czy ogólnie w JS) this w metodzie będzie na 100% wskazywać na obiekt, jeżeli metoda zostanie wywołana w kontekście obiekt.metoda()
i podobno kluczowe właśnie jest, żeby po nazwie metody był nawias. Czyli jak mam np poniższy kod w czystym JS:
class user {
constructor(name, surname, age) { //funkcja konstruktora
this.name = name;
this.surname = surname;
this.age = age;
}
hello() {
console.log(`Użytkownik ma na imię ${this.name} ${this.surname} i ma ${this.age} lat. This w funkcji hello:`);
console.log(this);
}
secondFunction(){
console.log(`Funkcja secondFunction. Na co wskazuje this:`);
console.log(this);
console.log(`Wywołanie w funkcji secondFunction funkcji hello (na co wskazuje this?)`);
this.hello();
}
}
const newPerson = new user("Jan", "Lewandowski", 24);
newPerson.hello();
newPerson.secondFunction();
To this użyte w metodzie hello wskazuje na obiekt newPerson, bo wywołaliśmy to jako newPerson.hello()
. Tak samo jak w metodzie secondFunction()
wywołamy metodę hello()
, to this
i tak będzie wskazywać na ten obiekt, żadne wiązanie nie zostanie zgubione.
Przeczytałem też w poniższej dokumentacji Reacta,
https://pl.reactjs.org/docs/handling-events.html
że "Należy zwrócić szczególną uwagę na znaczenie this funkcjach zwrotnych (ang. callbacks) używanych w JSX. W JavaScripcie metody klasy nie są domyślnie dowiązane do instancji. Jeśli zapomnisz dowiązać metodę this.handleClick
i przekażesz ją jako atrybut onClick
, to this przy wywołaniu będzie miało wartość undefined.
To zachowanie nie jest specyficzne dla Reacta; tak właśnie działają funkcje w JavaScripcie. Generalnie, jeśli odwołujesz się do metody bez () po nazwie, jak na przykład onClick={this.handleClick}
, pamiętaj, aby zawsze dowiązywać ją do instancji."
Czyli mam rozumieć, że w kodzie z JSfiddle konieczne było zbindowanie metoda, gdyż w buttonie napisaliśmy this.handleMessageButton
, BEZ nawiasów, więc wiązanie this
zostało zgubione. Tylko teraz mam jeszcze pytanie, dlaczego w tym miejscu nie można napisać this.handleMessageButton()
, czyli Z nawiasami? Jak próbowałem tak zrobić, to wywala mi błąd, a jak kiedyś programowałem w czystym JS, to mogłem bez problemu za pomocą onClick
a wywoływać funkcję z nawiasami?