2016-01-26 14 views
5

Ich lerne ReactJS und Redux, und ich kann nicht herausfinden, wie Zugriff auf meine TextField-Instanz erhalten, während Bindung onChange Rückruf an this binden.Wie kann man einen Callback mit ReactJS, Redux und ES2015 korrekt an 'this' binden?

(Ich bin material-ui für dieses Beispiel, aber ich würde ohne sie ganz das gleiche Problem auftritt)

import React, {Component} from 'react'; 
import { connect } from 'react-redux'; 
import { setDataValue } from './actions/data'; 
import TextField from 'material-ui/lib/text-field'; 
import Paper from 'material-ui/lib/paper'; 

export class DataInput extends Component { 
    constructor(props){ 
     super(props); 
    } 

    handleTextChange() { 
     this.props.setDataValue(document.getElementById('myField').value); 
    } 

    render(){ 
     return (
      <Paper style={{ 
       width: '300px', 
       margin: '10px', 
       padding: '10px' 
      }}> 
       <TextField 
        id='myField' 
        defaultValue={this.props.data.value} 
        onChange={this.handleTextChange.bind(this)} /> 
      </Paper> 
     ); 
    } 
} 

export default connect(
    (state) => ({data: state.data}), 
    {setDataValue} 
)(DataInput); 

Ich verwende eine Lösung, die finde ich hässlich (nicht wiederverwendbar => nicht sehr ' Komponente freundlich ') durch ein id auf meinem TextField- Einstellung und den Zugriff auf seinen Wert mit document.getElementById('myField').value

Wie könnte ich diese id loszuwerden, und es mit so etwas wie textFieldRef.value in meinem Rückruf zugreifen?

Ich habe versucht, ohne .bind(this), die mir durch this Zugriff auf meine Textfield-Instanz gibt, aber ich kann meine zugreifen this.props.setDataValue() Funktion nicht mehr da this nicht auf meinen Klassenkontext binded wird.

Vielen Dank!

Antwort

14

Vermeiden Sie Anrufe wie document.getElementById innerhalb einer React-Komponente. React wurde bereits entwickelt, um teure DOM-Aufrufe zu optimieren. Sie arbeiten damit gegen das Framework. Wenn Sie wissen möchten, wie Referenz-DOM-Knoten in React angezeigt werden, lesen Sie die Dokumentation here.

In dieser Situation benötigen Sie jedoch keine Referenzen. Ein Platzhalter (oder eine ID) auf TextField wird nicht unbedingt funktionieren. Was Sie referenzieren, ist ein React-Element, kein DOM-Knoten.

Verwenden Sie stattdessen besser den Rückruf onChange. Die an onChange übergebene Funktion wird mit einem event Argument aufgerufen. Sie können dieses Argument verwenden, um den Eingabewert zu erhalten. (Siehe die Reaktion event system.)

Ihre Event-Handler sollte wie folgt aussehen:

handleTextChange(event) { 
    this.props.setDataValue(event.target.value); 
} 

Und Ihre TextField sollte wie folgt aussehen:

<TextField 
    value={this.props.data.value} 
    onChange={event => this.handleTextChange(event)} 
/> 

Hinweis: Use value NOT defaultValue.

+0

Vielen Dank für Ihre schnelle Antwort! Das war's, das Event, wie konnte ich das verpassen? Ich bin mir sehr bewusst, dass die Verwendung von document.getElementById eine sehr schlechte Praxis in React ist, aber ich konnte keine andere Lösung finden, daher meine Frage :) Ich hätte die Material-ui-Dokumentation sorgfältiger lesen sollen, nochmals vielen Dank . –

3

Verwenden Zustand zusammen mit Redux ist ein schlechter Stil. Das ist also ein Design-Problem des Codes.

Redux sollte zusammen mit funktionalen Komponenten verwendet werden und nicht mit Klasse-Komponenten.

I funktionale Komponente schlage vor, mit und syntetic Ereignis als Parameter an onChange Funktion wie folgt passieren:

const mapDispatchToProps = (dispatch) => { 
return { 
    onChange: (value) => { 
     dispatch(changeAction(value)) 
    } 
} 

und dann so etwas wie dies innerhalb des Elements verwenden:

<input onChange={ (e) => onChange(e.target.value)} 

Sie auch passieren können Elemente eigene Eigenschaften:

const mapDispatchToProps = (dispatch) => { 
+1

Diese Zeile ist nicht korrekt. Redux sollte mit funktionalen Komponenten und nicht mit Klassen verwendet werden. Formula redux docs Wenn Sie lokale Status, Lebenszyklusmethoden oder Leistungsoptimierungen hinzufügen müssen, können Sie sie konvertieren zu Klassen.-http://redux.js.org/docs/basics/UsageWithReact.html – Amila