No meu método de renderização, tenho algo como
<input type={dynamicTypeValue} value={dynamicValue} />
Se eu renderizar primeiro esta entrada como um número, (por exemplo, dynamicTypeValue = 'number'; dynamicValue = 5
), mas depois mudar a entrada para uma string: ( dynamicTypeValue = 'string'; dynamicValue = '01/01/2016'
) Eu recebo um aviso
que o novo valor não é um número válido:
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+)?
Este é o comportamento esperado?
Parece que estamos aplicando as alterações de prop em uma ordem incorreta. A lógica para acertar é solucionável em geral (para tipos conhecidos), mas pode ser complexo para ficar perfeito se quisermos minimizar as operações DOM.
Estou surpreso que este caso específico seja problemático porque este código deve garantir que sempre definimos .type
antes de quaisquer outros atributos em um <input>
:
Não sei por que isso não está funcionando conforme o planejado Não está totalmente claro para mim se definir o tipo primeiro sempre resolve casos como esses ou definir o tipo primeiro simplesmente causaria o mesmo aviso ao alternar para o outro lado.
(Veja também # 2242, que é algo que podemos querer que aconteça, mas pode ser difícil de implementar de forma limpa no sistema atual. Era mais fácil quando tínhamos wrappers compostos completos para esses componentes, mas não temos mais. Criando um novo elemento sempre que as mudanças de tipo podem ser surpreendentes porque significaria que a referência a esse componente muda durante a vida útil do componente que nunca tivemos em outro lugar.)
A solução mais fácil aqui é definir um key
na entrada que muda com o tipo para que um novo elemento de entrada seja criado quando o tipo mudar.
Pode ser causado pelo bug do pedido Object.assign V8? Ou isso foi antes dos 15?
@gaearon ainda está na versão 15
@gurinderhans Qual navegador? Além disso, você pode fornecer um jsfiddle que demonstre o problema?
@jimfb Aqui está.
Navegador: Chrome 50.0.2661.86 (64 bits)
JSFiddle: https://jsfiddle.net/mb90na04/1/
Seguindo o depurador do Chrome, encontrei o seguinte:
Existe esta linha de código, https://github.com/facebook/react/blob/master/src/renderers/dom/shared/ReactDOMComponent.js#L829 , que depois faz uma chamada para https://github.com/ facebook / react / blob / master / src / renderers / dom / client / wrappers / ReactDOMInput.js # L221 e então o valor da entrada é tentado ser alterado enquanto _updateDOMProperties
ainda não foi chamado para atualizar o elemento type
attribute, portanto, o aviso é gerado. Assim que _updateDOMProperties
é chamado, type
é definido antes de value
, como é suposto e tudo vai de acordo com o plano.
_ PS: Claro, remover a chamada para ReactDOMInput.updateWrapper
, dentro de switch case
elimina o aviso, mas isso pode ser necessário para alguns outros casos, pois também noto que é chamado se o elemento type
é textarea
._
Você pode verificar a mudança de tipo e não definir o valor ou atualizar o tipo e então definir o valor dentro de ReactDOMInput.updateWrapper
. Também estou me perguntando por que a chamada é necessária para casos como <input>
ou <textarea>
Aqui está um caso mais simples reproduzindo o problema: https://jsfiddle.net/97gr5e65/1/
Parece que só acontece se mudar de number
para text
. Também não consigo reproduzir o aviso no Safari ou Firefox no OS X. Ele também não parece ocorrer usando ReactTestUtils
.
Este foi um bug interessante de verificar, então eu fiz algumas pesquisas. Meu pensamento inicial foi apenas atribuir type
antes de value
no updateWrapper. Isso é lógico?
https://github.com/facebook/react/compare/master...nhunzaker : nh-input-change-fix? expand = 1
Isso elimina o bug, mas é muito simples. Parece superficial. O que você acha?
Podemos mover as chamadas .updateWrapper
abaixo da chamada _updateDOMChildren
(separando-as das chamadas getNativeProps)? Acho que essa é a melhor solução aqui e parece que deve funcionar.
Sim. Também consegui obter cobertura de teste sobre isso. O valor é anulado pelo DOM quando o tipo muda de forma que o valor não seja mais válido ou se um novo valor não é válido atribuído.
Não relacionado, é muito bom que o JSDOM pegue isso.
Ainda acontece com a versão 16.4.1
Comentários muito úteis
Ainda acontece com a versão
16.4.1