1
votes

Impossible d'obtenir la valeur réelle d'une entrée dans react

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"


0 commentaires

4 Réponses :


0
votes

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


0 commentaires

0
votes

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;


0 commentaires

0
votes

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

Essayez-le ici!


0 commentaires

2
votes

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


2 commentaires

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 ()})