Você quer solicitar um recurso ou relatar um bug ?
Erro
Qual é o comportamento atual?
Ao renderizar uma lista de itens com key
definida como propriedade única em cada elemento de item, se a ordem dos itens mudar em relação à renderização anterior, os elementos de item cujos índices mudaram são renderizados novamente (uma nova instância é criada) em vez de - usando a instância existente (mapeada por meio de chave).
Por exemplo, https://codesandbox.io/s/r5p48kzop
Renderizando uma lista boxes
com cada caixa tendo id
, top
, left
& color
props. A cada 750ms
, atualizamos os valores ( top
, left
) de todos os elementos dentro do array boxes
.
Durante a atualização, se a ordem dos elementos não mudar, cada caixa será animada em sua nova posição. No entanto, se descomentarmos a linha 31, que embaralha as caixas, então apenas os elementos que mantêm sua posição da renderização anterior são animados para novas posições.
Você pode observar esse comportamento na sandbox. Com _shuffle
ativado, às vezes as caixas saltam para suas novas posições, enquanto com _shuffle
desativado elas sempre são animadas.
Se o comportamento atual for um bug, forneça as etapas para reproduzir e, se possível, uma demonstração mínima do problema. Cole o link para o seu exemplo JSFiddle (https://jsfiddle.net/Luktwrdm/) ou CodeSandbox (https://codesandbox.io/s/new) abaixo:
https://codesandbox.io/s/r5p48kzop
Qual é o comportamento esperado?
Independentemente da ordem de boxes
todos os elementos da caixa devem ser animados em suas novas posições, pois eles têm a propriedade key
exclusiva definida neles.
Quais versões do React e quais navegadores / sistemas operacionais são afetados por esse problema?
Reaja 16.3.2
& 16.4.1
, Chrome, MacOS.
Ei @ dhruvparmar372!
Esta parece ser uma limitação do DOM. Para demonstrar isso, criei este JSFiddle que altera a ordem de dois nós DOM e, em seguida, aplica uma classe para acionar uma transição.
Acontece que você pode contornar esse problema disparando um refluxo entre alterar a ordem e atualizar as propriedades da animação.
Eu adicionei um pouco de código ao seu CodeSandbox para torná-lo visível quando um componente é recriado pelo React, alterando <Box />
para ser um componente de classe e criando um id único no construtor. Como você pode ver, o ID permanecerá consistente: https://codesandbox.io/s/jn42wvl343
Além disso, apliquei a solução alternativa de refluxo ao seu exemplo, dividindo a atualização em dois setState
s. O primeiro mudará a ordem, depois acionamos um refluxo e depois mudamos a posição. Isso parece funcionar bem no Chrome, Firefox, Safari e Edge (CodeSandbox não oferece suporte ao IE11, então não pude testar nesse navegador).
hey @ philipp-spiess obrigado por esclarecer o problema e os exemplos para a solução alternativa.
Oi @ philipp-spiess
Eu tenho o mesmo problema com a classificação da lista 😔
Infelizmente, seu exemplo Codesandbox acima não está mais funcionando (
Aqui está um exemplo:
https://jsfiddle.net/9odLvbrx/
Ele classifica os itens no clique com uma transição CSS simples.
O problema é que a transição aparece apenas no item selecionado e omite o restante deles.
Eu sei como contornar o problema (comentado no código), mas funciona bem apenas em listas em que a quantidade de itens nunca muda. Então, se eu quiser adicionar ou remover um item - o material se torna incrivelmente complexo. Como posso usar sua solução de sobrecarga de refluxo para fazer isso acontecer no meu exemplo?
Desde já, obrigado! 😊
Comentários muito úteis
Ei @ dhruvparmar372!
Esta parece ser uma limitação do DOM. Para demonstrar isso, criei este JSFiddle que altera a ordem de dois nós DOM e, em seguida, aplica uma classe para acionar uma transição.
Acontece que você pode contornar esse problema disparando um refluxo entre alterar a ordem e atualizar as propriedades da animação.
Eu adicionei um pouco de código ao seu CodeSandbox para torná-lo visível quando um componente é recriado pelo React, alterando
<Box />
para ser um componente de classe e criando um id único no construtor. Como você pode ver, o ID permanecerá consistente: https://codesandbox.io/s/jn42wvl343Além disso, apliquei a solução alternativa de refluxo ao seu exemplo, dividindo a atualização em dois
setState
s. O primeiro mudará a ordem, depois acionamos um refluxo e depois mudamos a posição. Isso parece funcionar bem no Chrome, Firefox, Safari e Edge (CodeSandbox não oferece suporte ao IE11, então não pude testar nesse navegador).