Estou tentando encontrar a melhor maneira de remover um elemento de uma matriz no estado de um componente. Como não devo modificar a this.state
variável diretamente, existe uma maneira melhor (mais concisa) de remover um elemento de uma matriz do que o que tenho aqui?
onRemovePerson: function(index) {
this.setState(prevState => { // pass callback in setState to avoid race condition
let newData = prevState.data.slice() //copy array from prevState
newData.splice(index, 1) // remove element
return {data: newData} // update state
})
},
Obrigado.
Atualizada
Isso foi atualizado para usar o retorno de chamada em setState. Isso deve ser feito ao fazer referência ao estado atual durante a atualização.
javascript
reactjs
aherriot
fonte
fonte
Respostas:
A maneira mais limpa de fazer isso que eu já vi é com
filter
:fonte
_
vezes, o @HussienK é usado para representar um argumento não utilizado. Aqui, é o item atual na matriz.this.state
como entradathis.setState()
, mesmo que imutável, não é recomendado. consulte a minha resposta acima para obter uma referência aos documentos oficiais do React sobre este tópico.Você pode usar o
update()
auxiliar de imutabilidadereact-addons-update
, que efetivamente faz a mesma coisa sob o capô, mas o que você está fazendo está bem.fonte
react-addons-update
agora está obsoleto (2016).immutability-helper
está disponível como um substituto. github.com/kolodny/immutability-helper Além disso, veja a minha resposta abaixo sobre não modificar o this.state diretamente dentro do this.setState ().Acredito que a referência
this.state
dentro desetState()
é desencorajada (as atualizações de estado podem ser assíncronas ).Os documentos recomendam o uso
setState()
com uma função de retorno de chamada para que prevState seja passado em tempo de execução quando a atualização ocorrer. Então é assim que ficaria:Usando Array.prototype.filter sem ES6
Usando Array.prototype.filter com funções de seta do ES6
Usando auxiliar de imutabilidade
Usando Spread
Observe que em cada instância, independentemente da técnica usada,
this.setState()
é transmitido um retorno de chamada, não uma referência de objeto ao antigothis.state
;fonte
this.setState({ data: [...this.state.data.slice(0, index), ...this.state.data.slice(index + 1)] });
é errado usar emthis.state
vez daprevState
opção de retorno de chamada mostrada por @ user1628461?Aqui está uma maneira de remover o elemento da matriz no estado usando a sintaxe de expansão ES6.
fonte
Quero entrar aqui, mesmo que essa pergunta já tenha sido respondida corretamente por @pscl , caso alguém o mesmo problema que eu. Dos 4 métodos, optei por usar a sintaxe es6 com funções de seta devido à sua concisão e falta de dependência de bibliotecas externas:
Usando Array.prototype.filter com funções de seta do ES6
Como você pode ver, fiz uma pequena modificação para ignorar o tipo de índice (
!==
para!=
) porque no meu caso eu estava recuperando o índice de um campo de string.Outro ponto útil se você estiver vendo um comportamento estranho ao remover um elemento no lado do cliente é NUNCA usar o índice de uma matriz como a chave do elemento :
Quando o React difere do DOM virtual em uma alteração, ele analisa as chaves para determinar o que mudou. Portanto, se você estiver usando índices e houver um a menos na matriz, ele removerá o último. Em vez disso, use os IDs do conteúdo como chaves, assim.
O acima é um trecho de desta resposta de um post relacionado .
Feliz codificação para todos!
fonte
Você pode usar esta função, se desejar remover o elemento (sem índice)
fonte
Como mencionado em um comentário à resposta de ephrion acima, filter () pode ser lento, especialmente com matrizes grandes, pois ele procura um índice que parece já ter sido determinado. Esta é uma solução limpa, mas ineficiente.
Como alternativa, pode-se simplesmente "cortar" o elemento desejado e concatenar os fragmentos.
Espero que isto ajude!
fonte
Você pode tornar o código mais legível com uma função auxiliar de uma linha:
então use-o assim:
fonte
Apenas uma sugestão: no seu código, em vez de usar,
let newData = prevState.data
você pode usar o spread, que é introduzido no ES6, ou seja, você pode usarlet newData = ...prevState.data
para copiar a matrizTrês pontos ... representam operadores de expansão ou parâmetros de repouso ,
Ele permite que uma expressão ou string de matriz ou qualquer coisa que possa ser iterativa seja expandida em locais onde são esperados zero ou mais argumentos para chamadas de função ou elementos para matriz.
Além disso, você pode excluir o item da matriz com os seguintes
Espero que isso contribua !!
fonte
Aqui está uma maneira simples de fazer isso:
Espero que ajude!!!
fonte
delete
remove o item, mas os índices não são atualizados e, portanto, isso não seria uma boa abordagem para necessidades regulares.