Robię kurs ReactJS w Codecademy i zdezorientowali mnie.

(EDYCJA - pełny kod) Zdjęcie kodu:

Code

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
Trigosin Darom 19 listopad 2019, 15:20
Naprawdę zależy od tego, jak funkcja jest zdefiniowana i co robi.
 – 
Felix Kling
19 listopad 2019, 16:27

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 = () => { ... }
3
kind user 19 listopad 2019, 15:22
To tylko część historii. Funkcja strzałki jest również zdefiniowana jako właściwość klasy, co oznacza, że ​​jest faktycznie oceniana i ustawiana wewnątrz konstruktora, gdzie this wskazuje na instancję.
 – 
Felix Kling
19 listopad 2019, 16:29
scream = () => { ... }

render() {
    return <button onClick={()=>this.scream()}>AAAAAH!</button>;
  }
0
Siva Sai Niveditha 19 listopad 2019, 15:25
W metodzie onClick również musimy użyć funkcji strzałki
 – 
Siva Sai Niveditha
19 listopad 2019, 15:27
1
"w metodzie onClick również musimy użyć funkcji strzałki" Nie. Ponieważ this.scream jest funkcją strzałki, () => this.scream() i this.scream są identyczne.
 – 
Felix Kling
19 listopad 2019, 16:28

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')
);```
0
Pankaj 19 listopad 2019, 15:27
Tak, dzięki, czytałem o tym. Dlatego to, co widziałem w Codeacademy, nie pasowało.
 – 
Trigosin Darom
19 listopad 2019, 16:38

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>;
      }
0
Hemant 19 listopad 2019, 15:27

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.

0
zouari 19 listopad 2019, 16:48
Strzałka była tu oferowana kilka razy (choć nie odpowiadam na moje pytanie dotyczące kodu Codeacademy). Jednak autobind naprawdę sprawia, że ​​zastanawiam się, dlaczego projektanci javascriptu nie mogli tego zrobić dla nas niejawnie.
 – 
Trigosin Darom
19 listopad 2019, 17:19

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
0
Felix Kling 19 listopad 2019, 16:51
Właśnie zacząłem z Reactem, więc nie widziałem jeszcze, jak wygląda instancja komponentu klasy.
 – 
Trigosin Darom
19 listopad 2019, 17:36
To nie ma nic wspólnego z Reactem. Kiedy wywołujesz 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.
 – 
Felix Kling
19 listopad 2019, 17:42
Ale w opublikowanym przeze mnie kodzie nie ma wezwania do new Someclass(). Jest bardziej podobny do tego obj.method1();
 – 
Trigosin Darom
20 listopad 2019, 19:14
W pewnym momencie przekazujesz klasę do React. React tworzy instancję klasy.
 – 
Felix Kling
21 listopad 2019, 02:03