web-dev-qa-db-de.com

Wie binde ich mit ReactJS, Redux und ES2015 einen onChange-Rückruf an "this"?

Ich lerne ReactJS und Redux und kann nicht herausfinden, wie ich Zugriff auf meine TextField-Instanz erhalte, während ich den onChange-Rückruf an this binde.

(Ich verwende material-ui für dieses Beispiel, aber ich würde ohne es auf dasselbe Problem stoßen.)

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 ich als hässlich empfinde (nicht wiederverwendbar => nicht sehr "komponentenfreundlich"), indem ich eine id in meinem TextField setze und mit document.getElementById('myField').value auf deren Wert zugreife.

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

Ich habe es ohne .bind(this) versucht, wodurch ich über this auf meine TextField-Instanz zugreifen kann, aber ich kann nicht mehr auf meine this.props.setDataValue()-Funktion zugreifen, da this nicht an meinen Klassenkontext gebunden ist.

Vielen Dank !

8
Romain Durand

Vermeiden Sie die Verwendung von Aufrufen wie document.getElementById innerhalb einer React-Komponente. React wurde bereits entwickelt, um teure DOM-Aufrufe zu optimieren. Auf diese Weise arbeiten Sie im Rahmen des Frameworks. Wenn Sie wissen möchten, wie DOM-Knoten in React referenzieren, lesen Sie die Dokumente hier .

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

Verwenden Sie stattdessen den onChange-Callback besser. Die an onChange übergebene Funktion wird mit einem event-Argument aufgerufen. Sie können dieses Argument verwenden, um den Eingabewert abzurufen. (siehe Reacts Ereignissystem .)

Ihr Event-Handler sollte so aussehen:

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

Und dein TextField sollte so aussehen:

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

Hinweis: Verwenden Sie den Wert NOT defaultValue .

19
David L. Walsh

Die Verwendung von state zusammen mit Redux ist ein schlechter Stil. Dies ist also ein Designproblem des Codes. 

Redux sollte zusammen mit funktionalen Komponenten verwendet werden und nicht mit Klassenstilen. 

Ich schlage vor, eine funktionale Komponente zu verwenden und das syntetische Ereignis als Parameter an die onChange-Funktion zu übergeben:

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

und verwenden Sie dann so etwas innerhalb des Elements:

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

Sie können auch Elemente mit eigenen Eigenschaften übergeben:

const mapDispatchToProps = (dispatch) => {
1
Den Roman