2016-11-09 4 views
2

Ichs setState mit Chrom-API verwenden möchten, reagieren, aber ich bin in ein Problem laufen ...So verwenden Sie reagieren setState mit Chrom-API

componentDidMount() { 

    chrome.runtime.onMessage.addListener(function(request, sender) { 
     if (request.action == "getSource") { 
      this.setState({sourceCode: request.source}); 
     } 
    }); 
} 

habe ich versucht, die folgenden aber Chrom-API nicht erkennt setState als eine Funktion, so ist, dann habe ich versucht, erste request.source als Variable zu speichern ...

componentDidMount() { 
    var source = ""; 
    chrome.runtime.onMessage.addListener(function(request, sender) { 
     if (request.action == "getSource") { 
      source = request.source; 
     } 
    }); 
    this.setState({sourceCode: source}); 
} 

Aber wenn ich die folgende versuchen, source bleibt ein leerer String. Ich kann nicht herausfinden, warum seit source auf request.source gesetzt wird. Wie kann ich das beheben?

EDIT

ich als so ein Skript nenne ...

chrome.tabs.executeScript(null, { 
     file: 'src/js/scripts/getPageSource.js' 
    }, function() { 
    ... 

und im Script Ich habe einfach die folgende ...

chrome.runtime.sendMessage({ 
    action: "getSource", 
    source: DOMtoString(document) 
}); 

Wo DOMtoString Funktion Gibt eine Zeichenfolge zurück. Es ist die von meiner componentDidMount gefangen, die ich durch den Ausdruck auf der Konsole innerhalb der if-Anweisung verifiziert habe.

Es ist mir aufgefallen, dass die addListener asynchron ist. Gibt es eine Möglichkeit, das Ergebnis im Staat zu speichern?

+0

Bitte bearbeiten Sie die Frage zum Thema: Fügen Sie ein ** complete ** [mcve] ein, das das Problem dupliziert. Einschließlich * manifest.json *, einige der Hintergrund- und * Inhaltsskripte. Fragen, die Debugging-Hilfe suchen ("** warum funktioniert dieser Code nicht? **") müssen Folgendes enthalten: ► das gewünschte Verhalten, ► ein bestimmtes Problem oder einen Fehler * und * ►den kürzesten Code, der für die Wiedergabe in der Frage erforderlich ist selbst**. Fragen ohne eine klare Problemstellung sind für andere Leser nicht nützlich. Siehe: "** Wie erstelle ich ein [mcve] **", [Was kann ich hier fragen?] (Http://stackoverflow.com/help/on-topic) und [ask]. – Makyen

+1

Ist Ihnen bewusst, dass setState asunchronous ist? Wenn Sie das Ergebnis sehen möchten, müssen Sie innerhalb einer Callback-Funktion innerhalb von setState() nach ihnen fragen. zB: this.setState ({sourceCode: source}, function() {console.log (this.state.sourceCode)}) – Falk

+0

@Makyen innerhalb der 'if' Anweisung, wenn ich die' source' Variable 'console.log' Ich bekomme die richtige Ausgabe. Aber außerhalb des 'addListener' bleibt' source' eine leere Zeichenkette. Ich bin mir nicht sicher, was du sonst noch brauchst. – Bolboa

Antwort

3

Sie müssen this binden, so ist es unverändert in dem Ereignis-Listener

chrome.runtime.onMessage.addListener(function(request, sender) { 
    if (request.action == "getSource") { 
     this.setState({sourceCode: request.source}); 
    } 
}.bind(this)); 

Ihr zweiter Versuch nicht funktioniert, weil der Rückruf asynchron ist. Sie müssen setState aufrufen, wenn der Rückruf zurückkehrt. Bei Ihrem zweiten Versuch registrieren Sie sich für den Listener aber dann sofort Aufruf setState.

Bearbeiten: Alternativ können Sie stattdessen zu arrow functions verwenden. Dies würde lexikalisch binden this so wäre es unverändert.

+3

Sie verwenden react und JSX - einfacher zu verwenden '=>' –

+0

Einverstanden. Ich würde '=>' als eine Option in Ihrer Antwort hinzufügen. – azium

+1

Ich bevorzugte den KISS-Ansatz, fügte ihn aber als Option hinzu. – AnilRedshift

Verwandte Themen