Xóa mục khỏi mảng trạng thái trong phản ứng


130

Câu chuyện là, tôi có thể xếp Bob, Sally và Jack vào một chiếc hộp. Tôi cũng có thể xóa khỏi hộp. Khi loại bỏ, không có khe nào được để lại.

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

Bây giờ tôi cần xóa, nói, "Bob". Mảng mới sẽ là:

["Sally", "Jack"]

Đây là thành phần phản ứng của tôi:

...

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

...

Ở đây tôi chỉ cho bạn một mã tối thiểu vì có nhiều mã hơn (onClick, v.v.). Phần quan trọng là xóa, loại bỏ, hủy "Bob" khỏi mảng nhưng removePeople()không hoạt động khi được gọi. Có ý kiến ​​gì không? Tôi đã xem xét điều này nhưng có thể tôi đã làm sai điều gì đó vì tôi đang sử dụng React.

Câu trả lời:


169

Để xóa một phần tử khỏi một mảng, chỉ cần thực hiện:

array.splice(index, 1);

Trong trường hợp của bạn:

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

2
Trong trường hợp của tôi đó là: array.splice(array, 1);Cảm ơn
Sylar

array.splice(array, 1);? Tôi đoán bạn cần chỉnh sửa nó..Bạn nên sử dụng các biến khác nhau ...
Rayon

61
Khi sử dụng React, bạn nên tránh trực tiếp thay đổi trạng thái của mình. Bạn nên tạo một Mảng mới và sử dụng setState().
iaretiga,

2
Tôi khuyên bạn nên sử dụng Array.from (this.state.items) thay vì toán tử spread trong trường hợp này. Điều này là do Array.from được thiết kế đặc biệt cho việc sử dụng này.
Francisco Hodge

2
Gợi ý nhỏ, hãy thêm dấu kiểm cho "index! == -1" trước khi nối mảng để ngăn việc xóa không mong muốn.
RoboBear

204

Khi sử dụng React, bạn không nên thay đổi trạng thái trực tiếp. Nếu một đối tượng (hoặc Array, cũng là một đối tượng) bị thay đổi, bạn nên tạo một bản sao mới.

Những người khác đã đề xuất sử dụng Array.prototype.splice(), nhưng phương pháp đó làm thay đổi Array, vì vậy tốt hơn là không nên sử dụng splice()với React.

Dễ sử dụng nhất Array.prototype.filter() để tạo một mảng mới:

removePeople(e) {
    this.setState({people: this.state.people.filter(function(person) { 
        return person !== e.target.value 
    })});
}

42
Có đây là cách khai báo. Một phương pháp thay thế sử dụng prevState và mũi tên chức năng:this.setState(prevState => ({ people: prevState.people.filter(person => person !== e.target.value) }));
Josh Morel

9
Đây phải là câu trả lời được chấp nhận theo thành ngữ React về trạng thái không bao giờ đột biến.
lux

9
hoặc sử dụng chỉ mục:this.state.people.filter((_, i) => i !== index)
mb21

2
có lát cắt là không thể thay đổi và ghép nối có thể biến đổi
Cassian

Vấn đề với câu trả lời này là nếu bạn có nhiều người trùng tên, bạn sẽ xóa tất cả những người này. Sử dụng các chỉ số an toàn hơn trong trường hợp bạn có thể có giá trị nhân bản
klugjo

40

Đây là một sự thay đổi nhỏ về phản ứng của Aleksandr Petrov khi sử dụng ES6

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

17

Sử dụng .spliceđể xóa mục khỏi mảng. Khi sử dụng delete, các chỉ mục của mảng sẽ không bị thay đổi nhưng giá trị của chỉ mục cụ thể sẽundefined

Phương thức splice () thay đổi nội dung của một mảng bằng cách loại bỏ các phần tử hiện có và / hoặc thêm các phần tử mới.

Cú pháp: 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);

Biên tập:

Như đã chỉ ra bởi justin-Grant , Theo quy tắc chung, Không bao giờ đột biến this.statetrực tiếp, vì việc gọi setState()sau đó có thể thay thế đột biến bạn đã thực hiện. Đối xử this.statenhư thể nó là bất biến.

Cách thay thế là, tạo bản sao của các đối tượng trong this.statevà thao tác với các bản sao, gán chúng lại bằng cách sử dụng setState(). Array#map, Array#filtervv có thể được sử dụng.

this.setState({people: this.state.people.filter(item => item !== e.target.value);});

3
Đảm bảo không sử dụng splice hoặc bất kỳ phương pháp nào thay đổi trực tiếp biến trạng thái của bạn. Thay vào đó, bạn sẽ muốn tạo một bản sao của mảng, xóa mục khỏi bản sao, rồi chuyển bản sao vào setState. Các câu trả lời khác có chi tiết về cách thực hiện việc này.
Justin Grant

12

Cách dễ dàng để xóa mục khỏi mảng trạng thái trong phản ứng:

khi bất kỳ dữ liệu nào xóa khỏi cơ sở dữ liệu và danh sách cập nhật mà không có API gọi thì thời điểm đó bạn chuyển id đã xóa vào hàm này và hàm này xóa đã xóa đã lưu trữ khỏi danh sách

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


1
Bạn có thể giải thích câu trả lời này khác với 8 câu trả lời khác cho câu hỏi trẻ ba tuổi này như thế nào không? Từ đánh giá
Wai Ha Lee

trong mã trên, nó sẽ tạo lại mảng dữ liệu mới nhưng bỏ qua "deletePostId" id này
ANKIT-DETROJA

sử dụngitem.post_id !== deletePostId
Nimish goel

3

Một số câu trả lời đã đề cập đến việc sử dụng 'splice', điều này đã làm như Chance Smith nói đã làm thay đổi mảng. Tôi khuyên bạn nên sử dụng lệnh gọi Phương thức 'slice' (Tài liệu cho 'slice' ở đây) để tạo một bản sao của mảng ban đầu.


3

Rất đơn giản Đầu tiên bạn xác định một giá trị

state = {
  checked_Array: []
}

Hiện nay,

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

1

Bạn quên sử dụng setState. Thí dụ:

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

Nhưng tốt hơn nên sử dụng filtervì nó không gây đột biến mảng. Thí dụ:

removePeople(e){
  var array = this.state.people.filter(function(item) {
    return item !== e.target.value
  });
  this.setState({
    people: array
  })
},

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 tài liệu để biết thêm thông tin

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.