695 votes

Un composant transforme une entrée non contrôlée de type texte en erreur contrôlée dans ReactJS.

Avertissement : Un composant modifie une entrée non contrôlée de type texte pour qu'elle soit contrôlée. Les éléments d'entrée ne doivent pas passer de non contrôlés à contrôlés (ou vice versa). Décidez d'utiliser un élément d'entrée contrôlé ou non contrôlé pendant toute la durée de vie du composant.*

Voici mon code :

constructor(props) {
  super(props);
  this.state = {
    fields: {},
    errors: {}
  }
  this.onSubmit = this.onSubmit.bind(this);
}

....

onChange(field, e){
  let fields = this.state.fields;
  fields[field] = e.target.value;
  this.setState({fields});
}

....

render() {
  return(
    <div className="form-group">
      <input
        value={this.state.fields["name"]}
        onChange={this.onChange.bind(this, "name")}
        className="form-control"
        type="text"
        refs="name"
        placeholder="Name *"
      />
      <span style={{color: "red"}}>{this.state.errors["name"]}</span>
    </div>
  )
}

4 votes

Quelle est la valeur initiale de fields dans l'État ?

2 votes

Constructor(props) { super(props) ; this.state = { fields : {}, erreurs : {} } this.onSubmit = this.onSubmit.bind(this) ; }

2 votes

3voto

zrna Points 340

Utilisation de Crochets React N'oubliez pas non plus de définir la valeur initiale.
J'utilisais <input type='datetime-local' value={eventStart} /> et initial eventStart était comme

const [eventStart, setEventStart] = useState();
au lieu de
const [eventStart, setEventStart] = useState(''); .

La chaîne vide entre parenthèses est la différence.
De même, si vous réinitialisez le formulaire après l'envoi comme je le fais, vous devez à nouveau le définir comme une chaîne vide, et pas seulement comme une parenthèse vide.

C'est juste ma petite contribution à ce sujet, peut-être que cela aidera quelqu'un.

3voto

Justinelimtz Points 1

J'ai rencontré le même avertissement en utilisant les react hooks. , Bien que j'aie déjà initialisé l'état initial auparavant en tant que:-

const [post,setPost] = useState({title:"",body:""})

Mais plus tard, j'ai remplacé une partie de l'objet d'état prédéfini par le gestionnaire d'événement onChange,

 const onChange=(e)=>{
        setPost({[e.target.name]:e.target.value})
    }

Solution J'ai résolu ce problème en copiant d'abord l'objet entier de l'état précédent (en utilisant les opérateurs d'étalement) puis en éditant par dessus,

 const onChange=(e)=>{
        setPost({...post,[e.target.name]:e.target.value})
    }

2voto

Daniel Segura Points 457

Dans mon cas, c'est à peu près ce que dit la réponse de Mayank Shukla. Le seul détail était que mon état manquait complètement la propriété que je définissais.

Par exemple, si vous avez cet état :

state = {
    "a" : "A",
    "b" : "B",
}

Si vous développez votre code, vous pourriez vouloir ajouter une nouvelle propriété. Ainsi, quelque part ailleurs dans votre code, vous pourriez créer une nouvelle propriété c dont la valeur est non seulement indéfinie sur l'état du composant mais la propriété lui-même est indéfinie.

Pour résoudre ce problème, assurez-vous d'ajouter c dans votre état et lui donner une valeur initiale appropriée.

Par exemple,

state = {
    "a" : "A",
    "b" : "B",
    "c" : "C", // added and initialized property!
}

J'espère avoir réussi à expliquer mon cas limite.

2voto

Muhammad Minhaj Points 64

La raison de ce problème est que lorsque la valeur du champ d'entrée est indéfinie, un avertissement est lancé par react. Si vous créez un changeHandler pour plusieurs champs d'entrée et que vous voulez changer l'état avec changeHandler, vous devez assigner la valeur précédente en utilisant l'opérateur by spread. Comme mon code ici.

constructor(props){
    super(props)
    this.state = {
        user:{
            email:'',
            password:''
        }
    }
}

// This handler work for every input field
changeHandler = event=>{
    // Dynamically Update State when change input value
    this.setState({
        user:{
            ...this.state.user,
            [event.target.name]:event.target.value
        }
    })
}

submitHandler = event=>{
    event.preventDefault()

    // Your Code Here...
}

render(){
    return (
        <div className="mt-5">

            <form onSubmit={this.submitHandler}>
                <input type="text" value={this.state.user.email} name="email" onChage={this.changeHandler} />

                <input type="password" value={this.state.user.password} name="password" onChage={this.changeHandler} />

                <button type="submit">Login</button>
            </form>

        </div>
    )
}

2voto

Latief Anwar Points 460

Comme ceci

value={this.state.fields && this.state.fields["name"] || ''}

travailler pour moi.

Mais j'ai défini l'état initial comme ceci :

this.state = {
  fields: [],
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X