2016-01-26 17 views
5

Sto imparando ReactJS e Redux e non riesco a capire come ottenere l'accesso all'istanza TextField mentre leghi la richiamata onChange a this.Come associare correttamente il callback di Change a "this" con ReactJS, Redux ed ES2015?

(sto usando material-ui per questo esempio, ma vorrei incontrare abbastanza lo stesso problema senza di esso)

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); 

sto usando una soluzione che trovo brutto (non riutilizzabile => non molto ' componente-friendly ') impostando un id sul mio TextField, e l'accesso il suo valore con document.getElementById('myField').value

Come potrei liberarmi di questo id, e accedervi con qualcosa come textFieldRef.value dentro il mio richiamata?

ho giudicato senza .bind(this), che mi dà l'accesso alla mia istanza TextField attraverso this, ma io non può più accedere al mio funzione this.props.setDataValue() dal this non è binded al mio contesto classe.

Grazie!

risposta

14

Evitare l'uso di chiamate come document.getElementById all'interno di un componente React. React è già progettato per ottimizzare le costose chiamate DOM, quindi stai lavorando contro il framework facendo così. Se vuoi sapere come fare riferimento ai nodi DOM in React, leggi i documenti here.

Tuttavia, in questa situazione non sono effettivamente necessari riferimenti. Posizionare un ref (o un ID) su TextField non funzionerà necessariamente. Quello a cui si fa riferimento è un elemento React, non un nodo DOM.

Utilizzare al meglio il callback onChange. La funzione passata a onChange viene chiamata con un argomento event. Puoi usare quell'argomento per ottenere il valore di input. (Vedi di event system React.)

vostro gestore di eventi dovrebbe essere simile a questo:

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

E il tuo TextField dovrebbe assomigliare a questo:

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

Nota: Use value NOT defaultValue.

+0

Grazie per la tua risposta rapida! È così, l'evento, come potrei mancarlo? Sono molto consapevole dell'utilizzo di document.getElementById essendo una pessima pratica in React, ma non riuscivo a capire un'altra soluzione, quindi la mia domanda :) Avrei dovuto leggere il materiale-ui documenti più attentamente, grazie ancora . –

3

L'utilizzo dello stato insieme a Redux è un cattivo stile. Quindi questo è un problema di progettazione del codice.

Redux doveva essere utilizzato insieme a componenti funzionali e non a quelli di classe.

Io suggerisco di usare componente funzionale e passare evento sintetica come parametro alla funzione di onChange in questo modo:

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

e quindi usare qualcosa di simile all'interno dell'elemento:

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

È possibile anche passare elementi propri proprietà:

const mapDispatchToProps = (dispatch) => { 
+1

Questa riga non è corretta 'Redux era pensato per essere usato insieme ai componenti funzionali e non a quelli di classe. Form i documenti di redux' Se e quando è necessario aggiungere lo stato locale, i metodi del ciclo di vita o le ottimizzazioni delle prestazioni, è possibile convertirli alle classi. - http://redux.js.org/docs/basics/UsageWithReact.html – Amila