Estou criando um componente React que aceita uma fonte de dados JSON e cria uma tabela classificável.
Cada uma das linhas de dados dinâmicas possui uma chave exclusiva, mas ainda estou recebendo um erro de:
Cada criança em uma matriz deve ter um suporte "chave" exclusivo.
Verifique o método de renderização do TableComponent.
Meu TableComponent
método de renderização retorna:
<table>
<thead key="thead">
<TableHeader columns={columnNames}/>
</thead>
<tbody key="tbody">
{ rows }
</tbody>
</table>
O TableHeader
componente é uma única linha e também possui uma chave exclusiva atribuída a ele.
Cada row
nos rows
é construído a partir de um componente com uma chave única:
<TableRowItem key={item.id} data={item} columns={columnNames}/>
E a TableRowItem
aparência é assim:
var TableRowItem = React.createClass({
render: function() {
var td = function() {
return this.props.columns.map(function(c) {
return <td key={this.props.data[c]}>{this.props.data[c]}</td>;
}, this);
}.bind(this);
return (
<tr>{ td(this.props.item) }</tr>
)
}
});
O que está causando o erro exclusivo de suporte de chave?
javascript
reactjs
Brett DeWoody
fonte
fonte
key
propriedade exclusiva . Isso ajudará o ReactJS a encontrar referências aos nós DOM apropriados e atualizar apenas o conteúdo dentro da marcação, mas não a renderizar novamente a tabela / linha inteira.rows
array ou, de preferência, um jsfiddle? Você não precisa de umkey
imóvel nathead
etbody
pela maneira.Respostas:
Você deve adicionar uma chave a cada filho e a cada elemento dentro dos filhos .
Dessa forma, o React pode lidar com a alteração mínima do DOM.
No seu código, cada um
<TableRowItem key={item.id} data={item} columns={columnNames}/>
está tentando renderizar alguns filhos dentro deles sem uma chave.Veja este exemplo .
Tente remover a
key={i}
partir do<b></b>
elemento dentro do div (e verificar o console).No exemplo, se não fornecermos uma chave para o
<b>
elemento e desejarmos atualizar apenas oobject.city
, o React precisará renderizar novamente a linha inteira versus apenas o elemento.Aqui está o código:
A resposta postada por @Chris na parte inferior entra em muito mais detalhes do que esta resposta. Por favor, dê uma olhada em https://stackoverflow.com/a/43892905/2325522
Reagir a documentação sobre a importância das chaves na reconciliação: Chaves
fonte
key
valor do suporte seja exclusivo para cada item e você esteja colocando okey
suporte no componente mais próximo dos limites da matriz. Por exemplo, no React Native, primeiro eu estava tentando colocarkey
prop em<Text>
componente. No entanto, eu tive que colocá-lo no<View>
componente que é o pai<Text>
. se Matriz == [(Exibir> Texto), (Exibir> Texto)], você precisará colocá-lo em Exibir. Não texto.Tenha cuidado ao iterar sobre matrizes !!
É um equívoco comum que o uso do índice do elemento na matriz seja uma maneira aceitável de suprimir o erro com o qual você provavelmente está familiarizado:
No entanto, em muitos casos, não é! Isso é antipadrão que, em algumas situações, pode levar a comportamentos indesejados .
Compreendendo o
key
suporteO React usa o
key
suporte para entender a relação do componente para o elemento DOM, que é usada para o processo de reconciliação . Portanto, é muito importante que a chave permaneça sempre única ; caso contrário, há uma boa chance do React misturar os elementos e alterar o incorreto. Também é importante que essas chaves permaneçam estáticas durante todas as renderizações para manter o melhor desempenho.Dito isto, nem sempre é necessário aplicar o acima, desde que se saiba que a matriz é completamente estática. No entanto, a aplicação de boas práticas é incentivada sempre que possível.
Um desenvolvedor do React disse nesta edição do GitHub :
Em suma, um
key
deve ser:Usando o
key
suporteConforme a explicação acima, estude cuidadosamente as seguintes amostras e tente implementar, quando possível, a abordagem recomendada.
Ruim (potencialmente)
Este é sem dúvida o erro mais comum visto ao iterar sobre uma matriz no React. Essa abordagem não é tecnicamente "errada" , é apenas ... "perigosa" se você não sabe o que está fazendo. Se você estiver iterando através de uma matriz estática, essa é uma abordagem perfeitamente válida (por exemplo, uma matriz de links no menu de navegação). No entanto, se você estiver adicionando, removendo, reordenando ou filtrando itens, precisará ter cuidado. Veja esta explicação detalhada na documentação oficial.
Mostrar snippet de código
Neste trecho, estamos usando uma matriz não estática e não estamos nos restringindo a usá-la como uma pilha. Essa é uma abordagem insegura (você verá o porquê). Observe como, à medida que adicionamos itens ao início da matriz (basicamente sem deslocamento), o valor de cada um
<input>
permanece no local. Por quê? Porque okey
não identifica exclusivamente cada item.Em outras palavras, a princípio
Item 1
temkey={0}
. Quando adicionamos o segundo item, o item superior se tornaItem 2
, seguido porItem 1
como o segundo item. No entanto, agoraItem 1
temkey={1}
e nãokey={0}
mais. Em vez disso,Item 2
agora temkey={0}
!!Como tal, o React acha que os
<input>
elementos não foram alterados, porque aItem
chave with0
está sempre no topo!Então, por que essa abordagem às vezes é ruim?
Essa abordagem é arriscada apenas se a matriz for filtrada, reorganizada ou se os itens forem adicionados / removidos. Se é sempre estático, é perfeitamente seguro de usar. Por exemplo, um menu de navegação como
["Home", "Products", "Contact us"]
pode ser iterado com segurança por esse método, porque você provavelmente nunca adicionará novos links ou os reorganizará.Em resumo, é aqui que você pode usar o índice com segurança como
key
:Se, no snippet acima, empurrássemos o item adicionado ao final da matriz, a ordem para cada item existente sempre estaria correta.
Muito mal
Embora essa abordagem provavelmente garanta a exclusividade das chaves, ela sempre forçará a reagir para renderizar novamente cada item da lista, mesmo quando isso não for necessário. Essa é uma solução muito ruim, pois afeta muito o desempenho. Sem mencionar que não se pode excluir a possibilidade de uma colisão de chave no caso de
Math.random()
produzir o mesmo número duas vezes.Muito bom
Essa é sem dúvida a melhor abordagem, pois usa uma propriedade exclusiva para cada item no conjunto de dados. Por exemplo, se
rows
contiver dados buscados em um banco de dados, pode-se usar a Chave Primária da tabela ( que geralmente é um número de incremento automático ).Boa
Essa também é uma boa abordagem. Se o seu conjunto de dados não contiver nenhum dado que garanta exclusividade ( por exemplo, uma matriz de números arbitrários ), é possível que haja uma colisão de chave. Nesses casos, é melhor gerar manualmente um identificador exclusivo para cada item no conjunto de dados antes de iterá-lo. De preferência, ao montar o componente ou quando o conjunto de dados é recebido ( por exemplo, de
props
ou de uma chamada de API assíncrona ), para fazer isso apenas uma vez , e não sempre que o componente é renderizado novamente. Já existem algumas bibliotecas disponíveis que podem fornecer essas chaves. Aqui está um exemplo: react-key-index .fonte
toString()
converter em sequência em vez de sair como número. Isso é importante para lembrar?key
. Não sei por que eles estão convertendo.key
sempre acaba sendo uma String de qualquer maneira.Isso pode ou não ajudar alguém, mas pode ser uma referência rápida. Isso também é semelhante a todas as respostas apresentadas acima.
Eu tenho muitos locais que geram lista usando a estrutura abaixo:
Após algumas tentativas e erros (e algumas frustrações), a adição de uma propriedade-chave ao bloco mais externo resolveu a questão. Observe também que a tag <> agora é substituída pela tag agora.
Obviamente, tenho usado ingenuamente o índice de iteração (índice) para preencher o valor da chave no exemplo acima. Idealmente, você usaria algo exclusivo para o item da lista.
fonte
Aviso: Cada filho em uma matriz ou iterador deve ter um suporte "chave" exclusivo.
Este é um aviso, pois os itens da matriz sobre os quais iremos repetir precisarão de uma semelhança única.
O React manipula a renderização do componente de iteração como matrizes.
A melhor maneira de resolver isso é fornecer índice nos itens da matriz que você irá repetir. Por exemplo:
O índice é React adereços internos.
fonte
Basta adicionar a chave exclusiva aos seus componentes
fonte
Verifique: chave = undef !!!
Você também recebeu a mensagem de aviso:
se seu código estiver completo corretamente, mas se estiver ativado
someValue é indefinido !!! Por favor, verifique isso primeiro. Você pode economizar horas.
fonte
A melhor solução de definir chave única em reagir: dentro do mapa, você inicializou o nome post e depois define key por key = {post.id} ou, no meu código, você vê eu defino o nome do item e depois defino key by key = {item.id }:
fonte
Este é um aviso, mas abordar isso fará com que o Reacts torne muito mais RÁPIDO ,
Isso ocorre porque é
React
necessário identificar exclusivamente cada item da lista. Digamos que se o estado de um elemento dessa lista for alterado no ReactsVirtual DOM
, o React precisará descobrir qual elemento foi alterado e em que local do DOM ele deve ser alterado, para que o DOM do navegador esteja sincronizado com o Reacts Virtual DOM.Como solução, basta introduzir um
key
atributo para cadali
tag. Estekey
deve ser um valor exclusivo para cada elemento.fonte
key
suporte. Se você não fornecer um, o React atribuirá um automaticamente (o índice atual da iteração).key={i}
. Portanto, depende dos dados que sua matriz contém. Por exemplo, se você tiver a lista["Volvo", "Tesla"]
, obviamente o Volvo é identificado pela chave0
e o Tesla com1
- porque essa é a ordem em que eles aparecerão no loop. Agora, se você reordenar a matriz, as chaves serão trocadas. Para o React, como "objeto"0
ainda está no topo, ele interpretará essa alteração como "renomear", em vez de reordenar. As chaves corretas aqui precisariam estar, em ordem,1
então0
. Você nem sempre reordena o tempo de execução, mas quando o faz, é um risco.Isso resolverá o problema.
fonte
Eu estava encontrando essa mensagem de erro por
<></>
ter sido retornado para alguns itens da matriz quando, em vez disso,null
precisa ser retornado.fonte
Corrigi isso usando o Guid para cada chave como esta: Generating Guid:
E, em seguida, atribuindo esse valor aos marcadores:
fonte
Basicamente, você não deve usar o índice da matriz como uma chave exclusiva. Em vez disso, você pode usar a
setTimeout(() => Date.now(),0)
para definir a chave exclusiva ou o uuid único ou qualquer outra maneira que gere uma identificação exclusiva, mas não o índice da matriz como a identificação exclusiva.fonte