Wie verwendet man Pfeilfunktionen (öffentliche Klassenfelder) als Klassenmethoden?

Lesezeit: 6 Minuten

Wie verwendet man Pfeilfunktionen offentliche Klassenfelder als Klassenmethoden
Ben

Ich bin neu in der Verwendung von ES6-Klassen mit React, zuvor habe ich meine Methoden an das aktuelle Objekt gebunden (siehe erstes Beispiel), aber erlaubt mir ES6, eine Klassenfunktion dauerhaft mit Pfeilen an eine Klasseninstanz zu binden? (Nützlich bei der Übergabe als Callback-Funktion.) Ich erhalte Fehler, wenn ich versuche, sie so zu verwenden, wie Sie es mit CoffeeScript können:

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);
  }

Also, wenn ich passieren würde SomeClass.handleInputChange zum Beispiel setTimeoutwäre es auf die Klasseninstanz beschränkt und nicht auf die window Objekt.

  • Es würde mich interessieren, die gleiche Antwort für zu wissen Typoskript

    – Mars Robertson

    23. Juni 2016 um 14:09 Uhr

  • Die Lösung von TypeScript ist die gleiche wie der ES7-Vorschlag (siehe akzeptierte Antwort). Dies wird von TypeScript nativ unterstützt.

    – Philipp Bully

    28. Juli 2016 um 14:43 Uhr


  • Für alle die hier landen eine interessante Lektüre zum Thema “Pfeilfunktionen in Klasseneigenschaften sind möglicherweise nicht so gut, wie wir denken”

    – Welke

    19. März 2019 um 10:44 Uhr

  • Sie sollten es vermeiden, Pfeilfunktionen in der Klasse zu verwenden, da sie nicht Teil des Prototyps sind und daher nicht von jeder Instanz geteilt werden. Es ist dasselbe, als würde man jeder Instanz dieselbe Kopie der Funktion geben.

    – Surabh Ranka

    20. August 2019 um 6:30 Uhr

  • @SourabhRanka Fügt kein hinzu this Bindung im Konstruktor auch tun?

    – GoldCredential

    14. August 2021 um 10:32 Uhr

Wie verwendet man Pfeilfunktionen offentliche Klassenfelder als Klassenmethoden
Kerl

Ihre Syntax ist etwas falsch, es fehlt nur ein Gleichheitszeichen nach dem Eigenschaftsnamen.

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

Dies ist eine experimentelle Funktion. Sie müssen experimentelle Funktionen in Babel aktivieren, damit dies kompiliert wird. Hier ist eine Demo mit aktiviertem Experiment.

Um experimentelle Funktionen in babel zu nutzen, können Sie das entsprechende Plugin von installieren Hier. Für diese spezielle Funktion benötigen Sie die transform-class-properties Plugin:

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

Sie können mehr über den Vorschlag für Klassenfelder und statische Eigenschaften lesen Hier


  • (Obwohl ich weiß, dass das außerhalb einer ES6-Klasse funktioniert), scheint es bei mir nicht zu funktionieren, babel wirft einen unerwarteten Token-Pfeil auf den ersten = bei handleInputChange =

    – Ben

    11. Juli 2015 um 22:16 Uhr

  • Sie sollten eine Erklärung abgeben, z. B. dass dies eine experimentelle Funktion für einen ES7-Vorschlag ist.

    – Felix Klinge

    11. Juli 2015 um 22:23 Uhr

  • Der aktuelle Spezifikationsentwurf wurde im September geändert, daher sollten Sie ihn nicht für Autobind verwenden, wie Babel es vorschlägt.

    – schick

    24. Oktober 2015 um 19:34 Uhr

  • Für Babel 6.3.13 müssen die Presets „es2015“ und „stage-1“ aktiviert sein, um dies zu kompilieren

    – Andreas

    21. Dezember 2015 um 23:58 Uhr

  • Es funktioniert, aber die Methode wird der Instanz im Konstruktor hinzugefügt, anstatt dem Prototyp hinzugefügt zu werden, und das ist ein großer Unterschied.

    – lib3d

    21. Januar 2016 um 17:17 Uhr


Wie verwendet man Pfeilfunktionen offentliche Klassenfelder als Klassenmethoden
Bergi

Nein, wenn Sie gebundene, instanzspezifische Methoden erstellen möchten, müssen Sie dies im Konstruktor tun. Sie können dafür jedoch Pfeilfunktionen verwenden, anstatt zu verwenden .bind auf einer Prototypmethode:

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

Da ist ein Vorschlag was es Ihnen ermöglichen könnte, das wegzulassen constructor() und die Zuweisung direkt in den Klassenbereich mit derselben Funktionalität einfügen, aber ich würde nicht empfehlen, dies zu verwenden, da es sehr experimentell ist.

Alternativ können Sie immer verwenden .bind, wodurch Sie die Methode für den Prototyp deklarieren und sie dann an die Instanz im Konstruktor binden können. Dieser Ansatz ist flexibler, da er es ermöglicht, die Methode von außerhalb Ihrer Klasse zu ändern.

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

1646630111 100 Wie verwendet man Pfeilfunktionen offentliche Klassenfelder als Klassenmethoden
kennesoft

Ich weiß, dass diese Frage ausreichend beantwortet wurde, aber ich habe nur einen kleinen Beitrag zu leisten (für diejenigen, die die experimentelle Funktion nicht nutzen möchten). Aufgrund des Problems, mehrere Funktionsbindungen im Konstruktor binden zu müssen und es chaotisch aussehen zu lassen, habe ich eine Hilfsmethode entwickelt, die nach dem Binden und Aufrufen des Konstruktors automatisch alle erforderlichen Methodenbindungen für Sie durchführt.

Angenommen, ich habe diese Klasse mit dem Konstruktor:

//src/components/PetEditor.jsx
import React from 'react';
class PetEditor extends React.Component {
  
   constructor(props){
        super(props);
        this.state = props.currentPet || {tags:[], photoUrls: []};
     
        this.tagInput = null;
        this.htmlNode = null;

        this.removeTag = this.removeTag.bind(this);
        this.handleChange = this.handleChange.bind(this);
        this.modifyState = this.modifyState.bind(this);
        this.handleKeyUp = this.handleKeyUp.bind(this);
        this.addTag = this.addTag.bind(this);
        this.removeTag = this.removeTag.bind(this);
        this.savePet = this.savePet.bind(this);
        this.addPhotoInput = this.addPhotoInput.bind(this);
        this.handleSelect = this.handleSelect.bind(this);
        
    }
    // ... actual method declarations omitted
}

Es sieht chaotisch aus, nicht wahr? Jetzt habe ich diese Hilfsmethode erstellt

//src/utils/index.js
/**
 *  NB: to use this method, you need to bind it to the object instance calling it
 */
export function bindMethodsToSelf(objClass, otherMethodsToIgnore=[]){
    const self = this;
    Object.getOwnPropertyNames(objClass.prototype)
        .forEach(method => {
              //skip constructor, render and any overrides of lifecycle methods
              if(method.startsWith('component') 
                 || method==='constructor' 
                 || method==='render') return;
              //any other methods you don't want bound to self
              if(otherMethodsToIgnore.indexOf(method)>-1) return;
              //bind all other methods to class instance
              self[method] = self[method].bind(self);
         });
}

Alles, was ich jetzt tun muss, ist, dieses Dienstprogramm zu importieren und meinem Konstruktor einen Aufruf hinzuzufügen, und ich muss nicht mehr jede neue Methode im Konstruktor binden. Der neue Konstruktor sieht jetzt sauber aus, wie folgt:

//src/components/PetEditor.jsx
import React from 'react';
import { bindMethodsToSelf } from '../utils';
class PetEditor extends React.Component {
    constructor(props){
        super(props);
        this.state = props.currentPet || {tags:[], photoUrls: []};
        this.tagInput = null;
        this.htmlNode = null;
        bindMethodsToSelf.bind(this)(PetEditor);
    }
    // ...
}

  • Ihre Lösung ist nett, deckt jedoch nicht alle Lebenszyklusmethoden ab, es sei denn, Sie deklarieren sie im zweiten Argument. Zum Beispiel: shouldComponentUpdate und getSnapshotBeforeUpdate

    – WebDeg Brian

    3. September 2018 um 14:35 Uhr

  • Ihre Idee ähnelt der automatischen Bindung, die eine merkliche Leistungsminderung aufweist. Sie müssen nur Funktionen binden, die Sie weitergeben. Sehen medium.com/@charpeni/…

    – Michael Freigeim

    10. Mai 2019 um 23:52 Uhr


Sie verwenden die Pfeilfunktion und binden sie auch im Konstruktor. Sie müssen also keine Bindung vornehmen, wenn Sie Pfeilfunktionen verwenden

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

ODER Sie müssen eine Funktion nur im Konstruktor binden, wenn Sie die normale Funktion wie unten verwenden

class SomeClass extends React.Component {
   constructor(props){
      super(props);
      this.handleInputChange = this.handleInputChange.bind(this);
   }

  handleInputChange(val){
    console.log('selectionMade: ', val);
  }
}

Auch das Binden einer Funktion direkt im Render wird nicht empfohlen. Es sollte immer im Konstruktor sein

963080cookie-checkWie verwendet man Pfeilfunktionen (öffentliche Klassenfelder) als Klassenmethoden?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy