2014-03-02 14 views
53

Ich kann keine React SyntheticKeyboardEvent-Handler für die Ereigniseigenschaften außer null registrieren.React: Tastaturereignishandler Alle "Null"

Ich habe die Komponente in einer Geige isoliert und bekomme das gleiche Ergebnis wie in meiner Anwendung. Kann jemand sehen, was ich falsch mache?

http://jsfiddle.net/kb3gN/1405/

var Hello = React.createClass({ 
    render: function() { 
     return (
     <div> 
     <p contentEditable="true" 
      onKeyDown={this.handleKeyDown} 
      onKeyUp={this.handleKeyUp} 
      onKeyPress={this.handleKeyPress}>Foobar</p> 
     <textarea 
      onKeyDown={this.handleKeyDown} 
      onKeyUp={this.handleKeyUp} 
      onKeyPress={this.handleKeyPress}> 
     </textarea> 
     <div> 
      <input type="text" name="foo" 
      onKeyDown={this.handleKeyDown} 
      onKeyUp={this.handleKeyUp} 
      onKeyPress={this.handleKeyPress} /> 
     </div> 
     </div> 
    ); 
    }, 

    handleKeyDown: function(e) { 
     console.log(e); 
    }, 

    handleKeyUp: function(e) { 
    console.log(e); 
    }, 

    handleKeyPress: function(e) { 
    console.log(e); 
    } 
}); 

React.renderComponent(<Hello />, document.body); 
+2

Wie in der Antwort akzeptiert: Sie Das Ereignisobjekt kann nicht direkt protokolliert werden. Sie können jedoch property spreading wie 'console.log ({... e});' verwenden, wenn Sie ES2015 verwenden, um alle verfügbaren Eigenschaften zu prüfen. –

Antwort

62

BinaryMuse zur Verfügung gestellt, die Antwort auf IRC. Stellt sich heraus, es ist nur eine Eigenart; Sie können nicht die Eigenschaften lesen direkt von SyntheticKeyboardEvent - Sie die Eigenschaften aus den Handler angeben müssen:

handleKeyUp: function(e) { 
console.log(e.type, e.which, e.timeStamp); 
}, 

http://jsfiddle.net/BinaryMuse/B98Ar/

+20

Dies geschieht, weil React die Ereignisobjekte für die Leistung wiederverwendet, also sind die Eigenschaften zu dem Zeitpunkt, an dem die Konsole sie nachschlägt, "null". Wenn Chrome das Objekt bei der Protokollierung sofort kopiert, tritt dieses "Problem" nicht auf. –

+0

Bis spät in die Show, aber angenommen, ich wollte dieses Ereignis erfassen, setState (someFunc, callbackWithEvent). Gibt es eine Möglichkeit, dieses Ereignis zu klonen, sodass das CallbackWithEvent das synthetische Ereignis empfängt? – Clev3r

+4

Wenn Sie den Status des Ereignisses zu der Zeit sehen möchten, als es console.logged war und nicht die Zeit, in der Sie es in der Konsole betrachten, melden Sie es als JSON an. Dies kopiert es nach Wert anstelle von Referenz. console.log (JSON.Stringify (Ereignis)) –

24

console.log() sind aynchronous und durch die Zeit, darauf zuzugreifen das Ereignis reagieren bereits Müll sammelte es (es nutzt die Veranstaltung aus Leistungsgründen wieder).

Für Debugging-Zwecke, die einfachste Sache reagieren zu sagen, zu tun, ist nicht, dass Ereignis

e.persist() // NOTE: don't forget to remove it post debug 
console.log(e) 

ich eine API-Dokumentation nicht zu verwerfen, wird das Verfahren zumindest in den Quellen dokumentiert https://github.com/facebook/react/blob/c78464f/src/renderers/shared/stack/event/SyntheticEvent.js#L155

+0

Ich habe versucht, den "X" -Wert für ein Berührungsereignis zu erhalten, aber wurde immer null, obwohl normale Mausklicks korrekt erfasst wurden. Das hat mein Problem gelöst. Vielen Dank! – Brett84c

2

Wie Riccardo Galli richtig angibt, wird das Protokollobjekt bereits zu dem Zeitpunkt, an dem Sie darauf in der Konsole zugreifen, als Garbage Collection erfasst.

Die Lösung, die ich verwende, ist nur einen Klon des Objekts zu protokollieren, so dass es nicht Müll gesammelt wird. Klonen kann in vielerlei Hinsicht getan werden, aber da ich lodash verwenden, ich log wie folgt aus:

handleKeyDown: function(e) { 
     console.log(_.cloneDeep(e))); 
    } 
1

Sie können auch die zugrunde liegende (original) Browser Ereignis aus der Synthetic*Event Wrapper über die nativeEvent Eigenschaft extrahieren. (. Genau wie bei @ Riccardo Anmerkung über e.persist(), es ist unklar, wie man eigentlich wissen, ohne den React.js Quellcode lesen) zB

handleKeyDown: function(e) { 
    console.log('keyDown:event', e.nativeEvent); 
},