Je développais un composant de réaction pour obtenir une valeur dans une entrée et l'afficher automatiquement dans une balise, en utilisant des refs.
Tout fonctionne bien, mais la valeur affichée est la valeur précédente.
Je ne sais vraiment pas maintenant comment résoudre ce problème. J'utilise l'événement onChange dans l'entrée pour changer l'état de ce qui sera affiché, il est clair que la valeur actuelle n'est pas prise, mais plutôt la valeur précédente
class Conversor extends Component {
constructor(props){
super(props)
this.state = {
value: null
}
this.output = this.output.bind(this)
}
output(){
console.log(this.state)
this.refs.output.innerHTML = this.state.value
}
render() {
return (
<div>
<h2>{this.state.inputValue}</h2>
<input ref="input" type="text" onChange={() => {this.setState({ value: this.refs.input.value }); this.output()}}/>
<label ref="output"></label>
</div>
);
}
}
Si je mets la valeur "Hello World" dans l'entrée, la valeur affichée est "Hello Worl", quand ce doit être le "Hello World"
4 Réponses :
La meilleure façon d'atteindre votre objectif est de ne pas utiliser les références. Voici comment procéder
class Conversor extends Component {
constructor(props){
super(props)
this.state = {
value: null
}
}
output = (e) =>{
this.setState({value: e.target.value }, () => {
this.refs.output.innerHTML = this.state.value
})
}
render() {
return (
<div>
<input ref="input" type="text" onChange={this.output}/>
<label ref="output"></label>
</div>
);
}
}
Si vous souhaitez toujours utiliser les refs , procédez comme suit,
class Conversor extends Component {
constructor(props){
super(props)
this.state = {};
}
handleChange = (e) => {
const { id, value } = e.target;
this.setState({
[id]: value
})
}
render() {
const { name, anotherName } = this.state;
return (
<div>
<h2>{name}</h2>
<input id="name" name="name" type="text" onChange={this.handleChange}/>
<h2>{anotherName}</h2>
<input id="anotherName" name="anotherName" type="text" onChange={this.handleChange}/>
</div>
);
}
}
Vous n'avez pas du tout besoin de lier votre fonction de gestionnaire d'entrée. Au lieu de faire cela, utilisez simplement une fonction de flèche comme _handleInputTextChange . Vérifiez ceci:
import React, { Component } from 'react';
class InputTextHandler extends Component {
constructor(props){
super(props)
this.state = {
inputValue: ''
}
}
_handleInputTextChange = e => {
const inputValue = e.target.value;
this.setState({inputValue})
console.log(inputValue)
}
render() {
return (
<div>
<input
type="text"
onChange={this._handleInputTextChange}/>
</div>
);
}
}
export default InputTextHandler;
Deux choses: saisissez la valeur de l'événement dans la méthode onChange et passez la méthode this.output comme deuxième argument à setState qui se déclenche après la mise à jour de l'état qui n'est pas une opération synchrone.
render() {
return (
<div>
<h2>{this.state.inputValue}</h2>
<input ref="input" type="text" onChange={event => {this.setState({ value:event.target.value }, this.output)}}/>
<label ref="output"></label>
</div>
);
}
Vous pouvez utiliser event pour ce faire sans avoir besoin de la fonction output () .
class Conversor extends Component {
constructor(props){
super(props)
this.state = {
value: null
}
}
render() {
return (
<div>
<h2>{this.state.inputValue}</h2>
<input ref="input" type="text" onChange={(e) => {this.setState({ value: e.target.value });}}/>
<label ref="output">{this.state.value}</label>
</div>
);
}
}
merci l'homme, fonctionne très bien. mais savez-vous pourquoi il a un résultat différent lorsque, par exemple, je mets une autre fonction dans l'attribut onChange?
Le problème dans votre cas est que setState () est une fonction asynchrone, lorsque vous appelez la fonction output (), l'état peut ne pas être mis à jour. Ce que vous pouvez faire pour cela, c'est passer votre fonction output () comme fonction de rappel à la fonction setState. setState ({valeur: e.target.value}, () => {this.output ()})