2017-04-22 3 views
0

Ich versuche grundsätzlich, die Ereignislistener zu verwenden und ein Ereignis für das Ereignis 'Nachricht' hinzuzufügen, das externe Ereignisse auslöst, wenn diese App eine Webansicht in einer mobilen App ist.ReactJS-Ereignisse vom EventListener Die Ansicht nicht aktualisieren

Das Problem ist, dass die Reaktion Komponente nicht aktualisiert, wenn das Ereignis kommt. Ich kann feststellen, dass das Ereignis in meine Event-Listener-Funktion kommt jedoch buchstäblich die Reaktion Komponente nicht aktualisiert, auch wenn ich setState.

Hier ist mein Code:

import React, { Component } from 'react'; 
    import logo from './logo.svg'; 
    import './App.css'; 

    var showIfEventHappenedAndReactUpdated = false; 

    class App extends Component { 

     componentDidMount() { 

      //event listener to get events from external views 
      //when this app is used as a webview for example 
      document.addEventListener('message', function(e){ 

       //I can see the event coming through here 
       //However, the react component itself doesn't update 
       showIfEventHappenedAndReactUpdated = true; 

       //I have even tried putting a this.setState({}) here but it doesn't work...as it doesn't update the react-component 

      }) 
     } 

     render() { 

     if(showIfEventHappenedAndReactUpdated){ 
      return (
       <div className="App"> 
       <p>Event Occured and React Updated</p> 
       </div> 
      ); 
     }else{ 
      return (
       <div className="App"> 
       <p>Event DID NOT OCCUR YET</p> 
       </div> 
      ); 
     } 

     } 
    } 

    export default App; 

aber wenn ich die 'p' Tag intern wie diese

import React, { Component } from 'react'; 
    import logo from './logo.svg'; 
    import './App.css'; 



    class App extends Component { 

     componentDidMount() { 

      //event listener to get events from external views 
      //when this app is used as a webview for example 
      document.addEventListener('message', function(e){ 

       document.getElementsByTagName('p')[0].innerHTML = "EVENT OCCURED" 
      }) 
     } 

     render() { 
      return (
       <div className="App"> 
       <p>Event HAS NOT Occured</p> 
       </div> 
      ); 
     } 

     } 
    } 

    export default App; 

DANN es funktioniert bekommen. Die einzige Linie Änderung war

document.getElementsByTagName('p')[0].innerHTML = "EVENT OCCURED" 

Ich brauche aber die Ansicht reagiert tatsächlich zu aktualisieren, anstatt den Text innerhalb eines rohen DOM-Elements zu ändern.

Was muss ich tun, um das zu erreichen?

+0

Ich habe nicht gestartet ReactJS noch, aber ich habe Dokument gelesen und festgestellt, dass React Render DOM (React Component), wenn Zustand Eigenschaften ändert, so wenn Sie verwenden Ereignis Listener als Komponente wird nicht geändert. Sie müssen jeden Zustandswert aktualisieren und es funktioniert gut. –

+0

@YogeshPatel Ich habe versucht, this.setState ({}) noch nicht aktualisiert die Komponente –

Antwort

0

Erhalten Sie keine Fehlermeldung, wenn Sie versuchen, im Ereignishandler setState zu setzen? addEventListener setzt dies auf das Ziel, an das der Handler gebunden war, was in Ihrem Fall ein Dokument sein sollte. Wenn Ihr Dokument nicht über eine setState-Methode verfügt, sollte dies einen Fehler verursachen.

Die einfache Verwendung einer Pfeilfunktion sollte das Problem beheben oder Ihren Handler explizit an den aktuellen binden, wenn Sie ihn als Ereignislistener hinzufügen.

Wenn Sie keine Fehlermeldung erhalten und Ihre Funktion nicht hilft, versuchen Sie, this.setState vor dem Hinzufügen des Ereignis-Listeners und innerhalb des Ereignis-Listeners zu protokollieren und zu überprüfen, ob sie die gleiche Funktion haben. Versuchen Sie alternativ, einen Callback zu Ihrem SetState hinzuzufügen, um zu überprüfen, ob er aufgerufen wird.

+0

versucht mit der Pfeilfunktion und Bindung der Rückruf .... immer noch nicht aktualisiert - Zunair Syed gerade jetzt bearbeiten –

+0

Ich werde versuchen um zu sehen, ob sie die gleiche Funktion sind mit der console.log wie du erwähnt –

0

Ihre Callback-Funktion ist nicht an die react-Komponente gebunden, daher ist setState nicht definiert. console.log (this) in Ihrem Callback zu sehen.

es zu beheben, entweder binden dies der Rückruf des (.bind (this)) oder einen Pfeil Funktion verwenden, wenn Sie babel und so weiter aufgebaut haben.

+0

versucht mit der Pfeil-Funktion und Bindung der Callback .... immer noch nicht aktualisiert –

0

Sie haben zwei Probleme in Ihrem Code bekommen, wie es zum Zeitpunkt des Schreibens ist dies:

  1. Ihre Funktion im Event-Listener nicht auf Ihr reagiert Element gebunden ist. Wie andere gesagt haben, wird die Verwendung der Pfeilsyntax dies beheben.

  2. Sie aktualisieren eine Nicht-Statusvariable. Reagieren Sie nur Ihre Komponente unter 3 Bedingungen machen: es neue Requisiten übergeben, rufen Sie setState() (mit einem neuen Zustand, und Sie müssen haben einen Zustand, in Ihrem Konstruktor zurückgegeben), oder Sie rufen this.forceUpdate(). Das Ändern einer globalen Variablen führt nicht zum Rendern.

+0

hey, so die Pfeil-Funktion hat es nicht behoben. Ich habe auch vorher versucht SetState ({meine Zustände hier}) und jetzt gerade versucht, dies.forceUpdate(). Keine haben funktioniert :( –

+0

Eine funktionierende Version Ihrer App: http://codepen.io/nivekmai/pen/qmNpWo – nivekmai

-1

Zuerst showIfEventHappenedAndReactUpdated ist nicht Teil der staatlichen Komponente so, wenn Sie es aktualisieren, wird die Komponente nicht bewusst ist, dass es aktualisieren muss.In Ihrer Komponente eine Konstruktor-Methode etwas wie folgt hinzufügen:

constructor(props){ 
    super(props); 
    this.state = { showIfEventHappenedAndReactUpdated: false }; 
} 

dann den Wert mit this.setState({showIfEventHappenedAndReactUpdated : true}) aktualisieren. Dadurch wird die Komponente erneut gerendert und der neue Wert wird verwendet.

Zweitens ist die Callback-Funktion nicht an den Geltungsbereich der Komponente gebunden und erstellt beim Aufruf einen neuen Bereich. Entweder verwenden .bind(this) auf den Funktionsaufruf wie folgt aus:

const callback = function(e){ 
    //do stuff 
} 
document.addEventListener('message', callback.bind(this)); 

Oder können Sie einen Pfeil Funktion verwenden, die nicht über eine eigene Umfang wie dies schafft:

document.addEventListener('message', (e)=>{ //do stuff };

+0

haben beide versucht, können bestätigen, dass sie keinen Unterschied machen ... reagieren Komponente nicht aktualisiert –

+1

Hier ist ein Arbeitsbeispiel https://codepen.io/iarry/pen/Emybqw –

Verwandte Themen