Excluir item da matriz de estados em react

130

A história é que eu deveria colocar Bob, Sally e Jack em uma caixa. Também posso remover qualquer um da caixa. Quando removido, nenhum slot é deixado.

people = ["Bob", "Sally", "Jack"]

Agora preciso remover, por exemplo, "Bob". A nova matriz seria:

["Sally", "Jack"]

Aqui está o meu componente de reação:

...

getInitialState: function() {
  return{
    people: [],
  }
},

selectPeople(e){
  this.setState({people: this.state.people.concat([e.target.value])})
},

removePeople(e){
  var array = this.state.people;
  var index = array.indexOf(e.target.value); // Let's say it's Bob.
  delete array[index];
},

...

Aqui eu mostro um código mínimo, pois há mais (onClick etc). A parte principal é excluir, remover, destruir "Bob" da matriz, mas removePeople()não está funcionando quando chamado. Alguma ideia? Eu estava olhando para isso, mas posso estar fazendo algo errado, pois estou usando o React.

Sylar
fonte

Respostas:

167

Para remover um elemento de uma matriz, basta:

array.splice(index, 1);

No seu caso:

removePeople(e) {
  var array = [...this.state.people]; // make a separate copy of the array
  var index = array.indexOf(e.target.value)
  if (index !== -1) {
    array.splice(index, 1);
    this.setState({people: array});
  }
},
MarcoS
fonte
2
No meu caso, foi: array.splice(array, 1);Obrigado
Sylar
array.splice(array, 1);? Eu acho que você precisa para editar it..You deve estar usando variáveis diferentes ...
Rayon
59
Ao usar o React, você geralmente deve evitar a mutação direta do seu estado. Você deve criar uma nova matriz e usar setState().
Iaretiga 31/03/16
2
Eu recomendo usar Array.from (this.state.items) em vez do operador de propagação neste caso. Isso ocorre porque o Array.from se destina especificamente a esse uso.
Francisco Hodge
2
Sugestão pequena, adicione uma verificação para "index! == -1" antes de emendar a matriz para evitar remoções indesejadas.
RoboBear #
200

Ao usar o React, você nunca deve alterar o estado diretamente. Se um objeto (ou Array, que também é um objeto) for alterado, você deverá criar uma nova cópia.

Outros sugeriram o uso Array.prototype.splice(), mas esse método modifica a matriz, portanto, é melhor não usar splice()com o React.

Mais fácil de usar Array.prototype.filter()para criar uma nova matriz:

removePeople(e) {
    this.setState({people: this.state.people.filter(function(person) { 
        return person !== e.target.value 
    })});
}
iaretiga
fonte
42
Sim, esta é uma maneira declarativa. Um método alternativo utilizando prevState e seta funções:this.setState(prevState => ({ people: prevState.people.filter(person => person !== e.target.value) }));
Josh Morel
9
Essa deve ser a resposta aceita pelo idioma React do estado de nunca sofrer mutação.
lux
9
ou usando o índice:this.state.people.filter((_, i) => i !== index)
mb21
2
existe fatia que é imutable e emenda que mutável
Cassian
O problema com esta resposta é que, se você tiver várias pessoas com o mesmo nome, removerá todas elas. Usando o índice é mais seguro nos casos em que você pode ter crédulos
klugjo
39

Aqui está uma pequena variação na resposta de Aleksandr Petrov usando o ES6

removePeople(e) {
    let filteredArray = this.state.people.filter(item => item !== e.target.value)
    this.setState({people: filteredArray});
}
Dmitry
fonte
17

Use .splicepara remover o item da matriz. Usando delete, os índices da matriz não serão alterados, mas o valor do índice específico seráundefined

O método splice () altera o conteúdo de uma matriz removendo os elementos existentes e / ou adicionando novos elementos.

Sintaxe: array.splice(start, deleteCount[, item1[, item2[, ...]]])

var people = ["Bob", "Sally", "Jack"]
var toRemove = 'Bob';
var index = people.indexOf(toRemove);
if (index > -1) { //Make sure item is present in the array, without if condition, -n indexes will be considered from the end of the array.
  people.splice(index, 1);
}
console.log(people);

Editar:

Como apontado por justin-grant , Como regra geral, nunca mude this.statediretamente, pois ligar setState()depois pode substituir a mutação que você fez. Trate this.statecomo se fosse imutável.

A alternativa é criar cópias dos objetos this.statee manipular as cópias, atribuindo-as de volta usando setState(). Array#map, Array#filteretc. podem ser usados.

this.setState({people: this.state.people.filter(item => item !== e.target.value);});
Rayon
fonte
3
Certifique-se de não usar emenda ou qualquer método que altere sua variável de estado diretamente. Em vez disso, você deseja fazer uma cópia da matriz, remover o item da cópia e passar a cópia para setState. Outras respostas têm detalhes sobre como fazer isso.
Justin Grant
12

Maneira fácil de excluir o item da matriz de estados em react:

quando qualquer dado é excluído do banco de dados e atualiza a lista sem a API chamar o tempo que você passa o ID excluído para esta função e essa função remove o excluído recuperado da lista

export default class PostList extends Component {
  this.state = {
      postList: [
        {
          id: 1,
          name: 'All Items',
        }, {
          id: 2,
          name: 'In Stock Items',
        }
      ],
    }


    remove_post_on_list = (deletePostId) => {
        this.setState({
          postList: this.state.postList.filter(item => item.post_id != deletePostId)
        })
      }
  
}

ANKIT-DETROJA
fonte
1
Você pode explicar como isso difere das outras 8 respostas nesta pergunta de três anos? Da avaliação
Wai Ha Lee
no código acima que vai recriar nova matriz de dados, mas ignorar "deletePostId" este id
ANKIT-DETROJA
useitem.post_id !== deletePostId
Nimish goel
3

Algumas respostas mencionadas usando 'emenda', que fizeram como Chance Smith disse, mutaram a matriz. Eu sugiro que você use a chamada de método 'slice' (o documento para 'slice' está aqui), que faz uma cópia da matriz original.

Arthur Chen
fonte
3

É muito simples primeiro você define um valor

state = {
  checked_Array: []
}

Agora,

fun(index) {
  var checked = this.state.checked_Array;
  var values = checked.indexOf(index)
  checked.splice(values, 1);
  this.setState({checked_Array: checked});
  console.log(this.state.checked_Array)
}
QC innodel
fonte
1

Você esqueceu de usar setState. Exemplo:

removePeople(e){
  var array = this.state.people;
  var index = array.indexOf(e.target.value); // Let's say it's Bob.
  delete array[index];
  this.setState({
    people: array
  })
},

Mas é melhor usar filterporque não muda a matriz. Exemplo:

removePeople(e){
  var array = this.state.people.filter(function(item) {
    return item !== e.target.value
  });
  this.setState({
    people: array
  })
},
Aleksandr Petrov
fonte
1
removePeople(e){
    var array = this.state.people;
    var index = array.indexOf(e.target.value); // Let's say it's Bob.
    array.splice(index,1);
}

Redfer doc para obter mais informações

Gibbs
fonte