J'ai un composant react simple avec la forme qui je pense avoir une entrée contrôlée:
import React from 'react';
export default class MyForm extends React.Component {
constructor(props) {
super(props);
this.state = {}
}
render() {
return (
<form className="add-support-staff-form">
<input name="name" type="text" value={this.state.name} onChange={this.onFieldChange('name').bind(this)}/>
</form>
)
}
onFieldChange(fieldName) {
return function (event) {
this.setState({[fieldName]: event.target.value});
}
}
}
export default MyForm;
Lorsque j'exécute mon application, j'obtiens l'avertissement suivant:
Avertissement: MyForm modifie une entrée non contrôlée de type texte à contrôler. Les éléments d'entrée ne doivent pas passer de non contrôlé à contrôlé (ou vice versa). Décider entre l'utilisation d'un élément d'entrée contrôlé ou non contrôlé pendant la durée de vie du composant
Je crois que mon entrée est contrôlée car elle a une valeur. Je me demande ce que je fais mal?
J'utilise React 15.1.0
la source
name={'question_groups.${questionItem.id}'}
?value
hélice a une valeur non nulle / non définie. Le prop n'a pas besoin de correspondre à une variable d'état (il pourrait simplement s'agir d'une constante et le composant serait toujours considéré comme contrôlé). La réponse d'Adam est plus correcte et devrait être acceptée.Lorsque vous effectuez le rendu de votre composant pour la première fois, il
this.state.name
n'est pas défini, il est donc évalué àundefined
ounull
, et vous finissez par passer àvalue={undefined}
ouvalue={null}
à votreinput
.Lorsque ReactDOM vérifie si un champ est contrôlé, il vérifie si
value != null
(notez que ce n'est!=
pas le cas!==
), et puisqueundefined == null
dans JavaScript, il décide qu'il n'est pas contrôlé.Ainsi, lorsque
onFieldChange()
est appelé,this.state.name
est défini sur une valeur de chaîne, votre entrée passe de non contrôlée à contrôlée.Si vous le faites
this.state = {name: ''}
dans votre constructeur, car'' != null
votre entrée aura une valeur tout le temps et ce message disparaîtra.la source
this.props.<whatever>
, ce qui était le problème de mon côté. Merci, Adam!render()
, ou une expression dans la balise elle-même - tout ce qui est évaluéundefined
. Heureux d'avoir pu aider!name
".undefined
soit transmise initialement. C'est plutôt le fait qu'ilthis.state.name
n'existe pas en tant que variable d'état qui rend l'entrée non contrôlée. Par exemple, avoirthis.state = { name: undefined };
entraînerait le contrôle de l'entrée. Il faut comprendre que ce qui compte, c'est d'où vient la valeur, et non quelle est la valeur.this.state = { name: undefined }
entraînerait toujours une entrée non contrôlée.<input value={this.state.name} />
desugars àReact.createElement('input', {value: this.state.name})
. Étant donné que l'accès à une propriété inexistante d'un objet renvoieundefined
, cela correspond exactement au même appel de fonction:React.createElement('input', {value: undefined})
s'ilname
n'est pas défini ou explicitement définiundefined
, React se comporte de la même manière. Vous pouvez voir ce comportement dans ce JSFiddle.Une autre approche pourrait être de définir la valeur par défaut dans votre entrée, comme ceci:
la source
Je sais que d'autres y ont déjà répondu. Mais un facteur très important ici peut aider d'autres personnes confrontées à un problème similaire:
Vous devez avoir un
onChange
gestionnaire ajouté dans votre champ de saisie (par exemple textField, case à cocher, radio, etc.). Gérez toujours l'activité via leonChange
gestionnaire.Exemple:
Lorsque vous travaillez avec la case à cocher, vous devrez peut-être gérer son
checked
état avec!!
.Exemple:
la source
Une solution simple pour résoudre ce problème consiste à définir une valeur vide par défaut:
la source
Un inconvénient potentiel avec la définition de la valeur du champ sur "" (chaîne vide) dans le constructeur est que le champ est un champ facultatif et n'est pas modifié. Sauf si vous effectuez un massage avant de publier votre formulaire, le champ sera conservé dans votre stockage de données sous la forme d'une chaîne vide au lieu de NULL.
Cette alternative évitera les chaînes vides:
la source
Lorsque vous utilisez
onChange={this.onFieldChange('name').bind(this)}
dans votre entrée, vous devez déclarer votre chaîne vide d'état comme valeur du champ de propriété.manière incorrecte:
manière correcte:
la source
Dans mon cas, il me manquait quelque chose de vraiment trivial.
<input value={state.myObject.inputValue} />
Mon état était le suivant lorsque j'ai reçu l'avertissement:
En alternant mon état pour référencer l'entrée de ma valeur , mon problème a été résolu:
la source
Si les accessoires de votre composant ont été passés en tant qu'état, mettez une valeur par défaut pour vos balises d'entrée
la source
Définissez une valeur sur la propriété 'name' dans son état initial.
la source
Une mise à jour pour cela. Pour l'utilisation de React Hooks
const [name, setName] = useState(" ")
la source
" "
et non""
? Cela vous fait perdre tout texte d'indication, et si vous cliquez et tapez, vous obtenez un espace sournois avant toutes les données que vous entrez.Cela ne se produit généralement que lorsque vous ne contrôlez pas la valeur du fichier lorsque l'application a démarré et après un événement ou une fonction déclenchée ou l'état a changé, vous essayez maintenant de contrôler la valeur dans le champ de saisie.
Cette transition de ne pas avoir le contrôle sur l'entrée, puis de le contrôler, est ce qui provoque le problème en premier lieu.
La meilleure façon d'éviter cela est de déclarer une valeur pour l'entrée dans le constructeur du composant. Pour que l'élément d'entrée ait une valeur dès le début de l'application.
la source
Pour définir dynamiquement les propriétés d'état des entrées de formulaire et les garder contrôlées, vous pouvez faire quelque chose comme ceci:
la source
Créez simplement un repli sur '' si le this.state.name est null.
Cela fonctionne également avec les variables useState.
la source