Robię kurs ReactJS w Codecademy i zdezorientowali mnie.
(EDYCJA - pełny kod) Zdjęcie kodu:
I nie ma żadnego konstruktora ani żadnego wywołania żadnej metody wiązania dla metody klasy scream
.
Jednak w dalszych ćwiczeniach mówią, że nie możesz tego zrobić.
Prawdopodobnie coś mi brakuje.
6 odpowiedzi
Najwyraźniej this.scream
jest funkcją strzałkową. Funkcja strzałki nie wymaga oprawy. Domyślnie wskazuje na właściwy kontekst.
scream = () => { ... }
this
wskazuje na instancję.
scream = () => { ... }
render() {
return <button onClick={()=>this.scream()}>AAAAAH!</button>;
}
this.scream
jest funkcją strzałki, () => this.scream()
i this.scream
są identyczne.
Musisz uważać na znaczenie tego w wywołaniach zwrotnych JSX. W JavaScript metody klas nie są domyślnie powiązane. Jeśli zapomnisz powiązać this.handleClick i przekażesz go do onClick, będzie to niezdefiniowane, gdy funkcja zostanie faktycznie wywołana.
To nie jest zachowanie specyficzne dla Reacta; jest częścią tego, jak działają funkcje w JavaScript. Ogólnie rzecz biorąc, jeśli odwołujesz się do metody bez () po niej, na przykład onClick={this.handleClick}
, powinieneś powiązać tę metodę.
Podczas definiowania komponentu za pomocą klasy ES6 typowym wzorcem jest procedura obsługi zdarzeń, która jest metodą klasy. Na przykład ten komponent Toggle renderuje przycisk, który pozwala użytkownikowi przełączać się między stanami „ON” i „OFF”:
class Toggle extends React.Component {
constructor(props) {
super(props);
this.state = {isToggleOn: true};
// This binding is necessary to make `this` work in the callback
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState(state => ({
isToggleOn: !state.isToggleOn
}));
}
render() {
return (
<button onClick={this.handleClick}>
{this.state.isToggleOn ? 'ON' : 'OFF'}
</button>
);
}
}
ReactDOM.render(
<Toggle />,
document.getElementById('root')
);```
Możesz po prostu użyć funkcji strzałkowej (nie ma potrzeby wiązania w konstruktorze).
scream = () => { console.log('Here') }
render() {
return <button onClick={this.scream}>AAAAAH!</button>;
}
Lub możesz wywołać tę funkcję bezpośrednio przez.
render() {
return <button onClick={() => console.log('Here')}>AAAAAH!</button>;
}
Do obsługi zdarzeń w celu powiązania funkcji z obiektem należy używać funkcji strzałek. Innym rozwiązaniem jest automatyczne powiązanie każdej funkcji w konstruktorze, na przykład:
class Test{
constructor(){
Object.getOwnPropertyNames(Test.prototype).forEach(
method => this[method] = this[method].bind(this));
}
Przeczytaj o dekoratorze @AutoBind, aby uzyskać więcej informacji.
i nie ma konstruktora ani żadnego wywołania żadnej metody bind dla metody klasy scream.
Musisz powiązać this
z instancją komponentu tylko wtedy, gdy metoda faktycznie używa this
wewnętrznie.
Tak nie jest w twoim przykładzie, więc nie ma potrzeby tego wiązać. Bez względu na sposób wykonania metody, zawsze da ona ten sam wynik.
Oto przykład bez Reacta, aby pokazać różnicę:
var obj = {
value: 42,
method1() { // doesn't use `this`
console.log("yey!");
},
method2() { // uses `this`
console.log(this.value);
},
};
obj.method1(); // works
obj.method2(); // works
var m1 = obj.method1;
var m2 = obj.method2;
m1(); // works
m2(); // BROKEN!
var m2bound = obj.method2.bind(obj);
m2bound(); // works
new SomeClass()
w JavaScript, tworzysz nową instancję klasy (obiektu). Metody są zazwyczaj wywoływane w instancji, a metoda może odwoływać się do instancji za pośrednictwem this
. Pytałeś, dlaczego metoda nie jest powiązana (z instancją komponentu), więc tak właśnie odpowiedziałem.
new Someclass()
. Jest bardziej podobny do tego obj.method1();