Usuń element z tablicy stanów w React

130

Chodzi o to, że powinienem być w stanie włożyć Boba, Sally i Jacka do pudełka. Mogę też wyjąć albo z pudełka. Po usunięciu nie ma miejsca.

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

Muszę teraz usunąć, na przykład „Bob”. Nowa tablica wyglądałaby następująco:

["Sally", "Jack"]

Oto mój składnik reagowania:

...

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];
},

...

Tutaj pokazuję minimalny kod, ponieważ jest w nim więcej (onClick itp.). Kluczową częścią jest usunięcie, usunięcie, zniszczenie "Bob" z tablicy, ale removePeople()nie działa po wywołaniu. Jakieś pomysły? Ja patrząc na to , ale mogę robić coś złego, ponieważ używam React.

Sylar
źródło

Odpowiedzi:

169

Aby usunąć element z tablicy, po prostu wykonaj:

array.splice(index, 1);

W Twoim przypadku:

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
źródło
2
W moim przypadku było to: array.splice(array, 1);Dzięki
Sylar
array.splice(array, 1);? Myślę, że musisz go edytować .. Powinieneś używać różnych zmiennych ...
Rayon
61
Używając Reacta, powinieneś generalnie unikać bezpośredniej mutacji swojego stanu. Powinieneś utworzyć nową tablicę i użyć setState().
iaretiga
2
Zalecam użycie Array.from (this.state.items) zamiast operatora spreadu w tym przypadku. Dzieje się tak, ponieważ Array.from jest specjalnie przeznaczony do tego zastosowania.
Francisco Hodge,
2
Drobna sugestia, przed połączeniem tablicy dodaj sprawdzenie „index! == -1”, aby zapobiec niechcianym usunięciom.
RoboBear
204

Korzystając z Reacta, nigdy nie powinieneś zmieniać stanu bezpośrednio. Jeśli obiekt (lub Arrayktóry jest również obiektem) zostanie zmieniony, powinieneś utworzyć nową kopię.

Inni sugerowali użycie Array.prototype.splice(), ale ta metoda mutuje Array, więc lepiej nie używać splice()z React.

Najłatwiejszy w użyciu Array.prototype.filter()do utworzenia nowej tablicy:

removePeople(e) {
    this.setState({people: this.state.people.filter(function(person) { 
        return person !== e.target.value 
    })});
}
iaretiga
źródło
42
Tak, to jest deklaratywny sposób. Alternatywna metoda wykorzystująca funkcje prevState i strzałek:this.setState(prevState => ({ people: prevState.people.filter(person => person !== e.target.value) }));
Josh Morel
9
Powinna to być akceptowana odpowiedź zgodnie z idiomem React o stanie braku mutacji.
lux
9
lub używając indeksu:this.state.people.filter((_, i) => i !== index)
mb21
2
jest kawałek, który jest niezmienny i łączy, że jest zmienny
Cassian
Problem z tą odpowiedzią polega na tym, że jeśli masz kilka osób o tym samym nazwisku, usuniesz je wszystkie. Korzystanie z indeksu jest bezpieczniejsze w przypadkach, w których możesz mieć
oszustów
40

Oto niewielka odmiana odpowiedzi Aleksandra Pietrowa za pomocą ES6

removePeople(e) {
    let filteredArray = this.state.people.filter(item => item !== e.target.value)
    this.setState({people: filteredArray});
}
Dmitry
źródło
17

Służy .splicedo usuwania elementu z tablicy. Używając delete, indeksy tablicy nie zostaną zmienione, ale wartość konkretnego indeksu ulegnie zmianieundefined

Metoda splice () zmienia zawartość tablicy, usuwając istniejące elementy i / lub dodając nowe elementy.

Składnia: 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);

Edytować:

Jak wskazał justin-grant , z reguły nigdy nie mutuj this.statebezpośrednio, ponieważ setState()późniejsze wywołanie może zastąpić dokonaną przez Ciebie mutację. Traktuj this.statetak, jakby było niezmienne.

Alternatywą jest tworzenie kopii obiektów w programie this.statei manipulowanie nimi, przypisując je z powrotem za pomocą setState(). Array#map, Array#filterItd. Mogą być wykorzystane.

this.setState({people: this.state.people.filter(item => item !== e.target.value);});
Sztuczny jedwab
źródło
3
Upewnij się, że nie używasz łącznika ani żadnej metody, która bezpośrednio zmienia zmienną stanu. Zamiast tego będziesz chciał utworzyć kopię tablicy, usunąć element z kopii, a następnie przekazać kopię do setState. Inne odpowiedzi zawierają szczegółowe informacje o tym, jak to zrobić.
Justin Grant
12

Łatwy sposób na usunięcie pozycji z tablicy stanów w reakcji:

kiedy jakiekolwiek dane usuwają się z bazy danych i aktualizują listę bez wywołania API tym razem przekazujesz usunięty identyfikator do tej funkcji i ta funkcja usuwa usunięte recored z listy

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
źródło
1
Czy możesz wyjaśnić, czym różni się to od 8 innych odpowiedzi na to trzyletnie pytanie? Z recenzji
Wai Ha Lee
w powyższym kodzie odtworzy nową tablicę danych, ale pominie „deletePostId” ten identyfikator
ANKIT-DETROJA
użytkowanieitem.post_id !== deletePostId
Nimish goel
3

Niektóre odpowiedzi wspominały o użyciu „splotu”, co, jak powiedział Chance Smith, spowodowało mutację tablicy. Sugerowałbym użycie wywołania metody „plasterek” (dokument „plasterek” jest tutaj), które tworzy kopię oryginalnej tablicy.

Arthur Chen
źródło
3

To bardzo proste. Najpierw określ wartość

state = {
  checked_Array: []
}

Teraz,

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
źródło
1

Zapomniałeś użyć setState. Przykład:

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
  })
},

Ale lepiej jest użyć, filterponieważ nie powoduje mutacji tablicy. Przykład:

removePeople(e){
  var array = this.state.people.filter(function(item) {
    return item !== e.target.value
  });
  this.setState({
    people: array
  })
},
Aleksandr Petrov
źródło
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);
}

Więcej informacji znajdziesz w dokumencie Redfer

Gibbs
źródło