Dans ma méthode de rendu, j'ai quelque chose comme
<input type={dynamicTypeValue} value={dynamicValue} />
Si je rend d'abord cette entrée sous forme de nombre, (par exemple dynamicTypeValue = 'number'; dynamicValue = 5
) mais que je change ensuite l'entrée en chaîne: ( dynamicTypeValue = 'string'; dynamicValue = '01/01/2016'
) J'obtiens un avertissement
que la nouvelle valeur n'est pas un nombre valide:
The specified value "01/01/2000" is not a valid number. The value must match to the following regular expression: -?(\d+|\d+\.\d+|\.\d+)([eE][-+]?\d+)?
DOMPropertyOperations.js:142 The specified value "01/01/2012" is not a valid number. The value must match to the following regular expression: -?(\d+|\d+\.\d+|\.\d+)([eE][-+]?\d+)?
Est-ce un comportement attendu?
On dirait que nous appliquons les changements d'accessoires dans un mauvais ordre. La logique pour y parvenir est résoluble en général (pour les types connus), mais pourrait être complexe à obtenir parfait si nous voulons minimiser les opérations DOM.
Je suis surpris que ce cas particulier soit problématique car ce code devrait garantir que nous définissons toujours .type
avant tout autre attribut sur un <input>
:
Je ne sais pas pourquoi cela ne fonctionne pas comme prévu. Il n'est pas tout à fait clair pour moi si le type de réglage en premier résout toujours des cas comme ceux-ci ou si le type de réglage en premier provoquerait simplement le même avertissement lors du changement de sens.
(Voir aussi # 2242, ce que nous souhaitons peut-être faire mais qui peut être difficile à implémenter proprement dans le système actuel. C'était plus facile lorsque nous avions des wrappers composites complets pour ces composants, mais nous ne le faisons plus. Créer un nouvel élément à chaque fois les changements de type pourraient être surprenants car cela signifierait que la référence à ce composant change pendant la durée de vie du composant que nous n'avons jamais ailleurs.)
La solution de contournement la plus simple consiste à définir un key
sur l'entrée qui change avec le type afin qu'un nouvel élément d'entrée soit créé lorsque le type change.
Peut-être être causé par un bogue de commande Object.assign V8? Ou était-ce avant 15 ans?
@gaearon c'est toujours dans la version 15
@gurinderhans Quel navigateur? En outre, pouvez-vous fournir un jsfiddle qui illustre le problème?
@jimfb Ici vous allez.
Navigateur: Chrome 50.0.2661.86 (64 bits)
JSFiddle: https://jsfiddle.net/mb90na04/1/
Suite au débogueur de chrome, j'ai trouvé ceci:
Il y a cette ligne de code, https://github.com/facebook/react/blob/master/src/renderers/dom/shared/ReactDOMComponent.js#L829 , qui passe ensuite un appel à https://github.com/ facebook / react / blob / master / src / renderers / dom / client / wrappers / ReactDOMInput.js # L221 et ensuite la valeur de l'entrée est essayée d'être modifiée alors que _updateDOMProperties
n'a pas encore été appelé pour mettre à jour l'attribut élément type
, ainsi l'avertissement est généré. Une fois que _updateDOMProperties
est appelé, type
est positionné avant value
, comme il est supposé et tout se passe comme prévu.
_ PS: Bien sûr, la suppression de l'appel à ReactDOMInput.updateWrapper
, à l'intérieur du switch case
supprime l'avertissement, mais cela peut être nécessaire dans d'autres cas car je remarque également qu'il est appelé si l'élément type
est textarea
._
Vous pouvez vérifier le changement de type, et non définir la valeur, ou mettre à jour le type, puis définir la valeur dans ReactDOMInput.updateWrapper
. Je me demande également pourquoi l'appel est requis pour des cas comme <input>
ou <textarea>
Voici un cas plus simple reproduisant le problème: https://jsfiddle.net/97gr5e65/1/
Cela ne semble se produire que si vous passez de number
à text
. Je ne parviens pas non plus à reproduire l'avertissement dans Safari ou Firefox sous OS X. Cela ne semble pas non plus se produire en utilisant ReactTestUtils
.
C'était un bug intéressant à vérifier, alors j'ai fouillé. Ma première pensée était simplement d'assigner type
avant value
dans le updateWrapper. Est-ce sain d'esprit?
https://github.com/facebook/react/compare/master...nhunzaker : nh-input-change-fix? expand = 1
Cela élimine le bogue, mais c'est trop simple. Cela semble peu profond. Qu'est-ce que tu penses?
Pouvons-nous déplacer les appels .updateWrapper
sous l'appel _updateDOMChildren
(en les séparant des appels getNativeProps)? Je pense que c'est la meilleure solution ici et il semble que cela devrait fonctionner.
Oui. J'ai également pu obtenir une couverture de test à ce sujet. La valeur est annulée par le DOM lorsque le type change de sorte que la valeur n'est plus valide, ou si une nouvelle valeur est affectée qui n'est pas valide.
Sans rapport, c'est plutôt cool que JSDOM prenne cela.
Cela arrive toujours avec la version 16.4.1
Commentaire le plus utile
Cela arrive toujours avec la version
16.4.1