J'apprends ReactJS et Redux et je ne vois pas comment obtenir un accès à mon instance TextField tout en liant son rappel onChange à this
.
(J'utilise material-ui pour cet exemple, mais je rencontrerais tout à fait le même problème sans cela)
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);
J'utilise une solution que je trouve laide (non réutilisable => pas très 'compatible avec les composants') en définissant une id
sur mon TextField et en accédant à sa valeur avec document.getElementById('myField').value
Comment pourrais-je me débarrasser de cette id
et y accéder avec quelque chose comme textFieldRef.value
dans mon rappel?
J'ai essayé sans .bind(this)
, ce qui me permet d'accéder à mon instance TextField via this
, mais je ne peux plus accéder à ma fonction this.props.setDataValue()
car this
n'est pas lié à mon contexte de classe.
Je vous remercie !
Évitez d’utiliser des appels tels que document.getElementById
dans un composant React. React est déjà conçu pour optimiser les appels DOM onéreux. Vous agissez ainsi contre le framework. Si vous voulez savoir comment référencer les noeuds DOM dans React, lisez le document here .
Cependant, dans cette situation, vous n'avez pas réellement besoin de références. Placer un ref (ou un ID) sur TextField
ne va pas forcément au travail. Ce que vous référencez est un élément React, pas un nœud DOM.
Utilisez plutôt le callback onChange
. La fonction passée à onChange
est appelée avec un argument event
. Vous pouvez utiliser cet argument pour obtenir la valeur d'entrée. (voir Système d'événements .)
Votre gestionnaire d'événement devrait ressembler à ceci:
handleTextChange(event) {
this.props.setDataValue(event.target.value);
}
Et votre TextField
devrait ressembler à ceci:
<TextField
value={this.props.data.value}
onChange={event => this.handleTextChange(event)}
/>
Remarque: Utilisez la valeur NOT defaultValue .
Utiliser l'état avec Redux est un mauvais style. C'est donc un problème de conception du code.
Redux devait être utilisé avec des composants fonctionnels et non ceux de style classique.
Je suggère d'utiliser un composant fonctionnel et de transmettre un événement syntetic en tant que paramètre à la fonction onChange comme ceci:
const mapDispatchToProps = (dispatch) => {
return {
onChange: (value) => {
dispatch(changeAction(value))
}
}
puis utilisez quelque chose comme ça à l'intérieur de l'élément:
<input onChange={ (e) => onChange(e.target.value)}
Vous pouvez également transmettre des propriétés propres aux éléments:
const mapDispatchToProps = (dispatch) => {