javascript - Hur man använder pilfunktioner (publika klassfält) som klassmetoder?


Jag är ny på att använda ES6-klasser med React, tidigare har jag bundit mina metoder till det aktuella objektet (visat i det första exemplet), men tillåter ES6 att jag permanent binder en klassfunktion till en klassinstans med pilar? (Användbart när man skickar som en callbackfunktion.) Jag får fel när jag försöker använda dem som man kan med CoffeeScript:

class SomeClass extends React.Component {

  // Instead of this
  constructor(){
    this.handleInputChange = this.handleInputChange.bind(this)
  }

  // Can I somehow do this? Am i just getting the syntax wrong?
  handleInputChange (val) => {
    console.log('selectionMade: ', val);
  }

Så att om jag skulle skicka SomeClass.handleInputChange till till exempel setTimeout, skulle det vara bundet till klassinstansen, och inte window-objektet.

Svar #1

Din syntax är något felaktig, det saknas bara ett likhetstecken efter egenskapsnamnet.

class SomeClass extends React.Component {
  handleInputChange = (val) => {
    console.log('selectionMade: ', val);
  }
}

Detta är en experimentell funktion. Du behöver aktivera experimentella funktioner i Babel för att få detta att kompilera. Här är en demonstration med experimentella funktioner aktiverade.

För att använda experimentella funktioner i Babel kan du installera den relevanta plugin från här. För denna specifika funktion behöver du transform-class-properties-plugin:

{
  "plugins": [
    "transform-class-properties"
  ]
}

Du kan läsa mer om förslaget för klassfält och statiska egenskaper här

Svar #2

Nej, om du vill skapa bundna, instansspecifika metoder måste du göra det i konstruktören. Du kan dock använda arrow-funktioner för det, istället för att använda .bind på en prototypmetod:

class SomeClass extends React.Component {
  constructor() {
    super();
    this.handleInputChange = (val) => {
      console.log('selectionMade: ', val, this);
    };
    …
  }
}

Det finns ett förslag som kan tillåta dig att utelämna constructor() och direkt lägga till tilldelningen i klassens omfång med samma funktionalitet, men jag skulle inte rekommendera att använda det eftersom det är mycket experimentellt.

Alternativt kan du alltid använda .bind, vilket låter dig deklarera metoden på prototypen och sedan binda den till instansen i konstruktorn. Detta tillvägagångssätt har större flexibilitet eftersom det tillåter att modifiera metoden från utsidan av din klass.

class SomeClass extends React.Component {
  constructor() {
    super();
    this.handleInputChange = this.handleInputChange.bind(this);
    …
  }
  handleInputChange(val) {
    console.log('selectionMade: ', val, this);
  }
}

Relaterade artiklar