Удалить элемент из массива состояний в React

131

История такова, что я смогу поместить Боба, Салли и Джека в коробку. Я тоже могу удалить из коробки. При снятии слота не остается.

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

Теперь мне нужно удалить, скажем, «Боб». Новый массив будет:

["Sally", "Jack"]

Вот мой компонент реакции:

...

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

...

Здесь я покажу вам минимальный код, так как это еще не все (onClick и т. Д.). Ключевой частью является удаление, удаление, уничтожение «Боба» из массива, но removePeople()он не работает при вызове. Любые идеи? Я смотрел на это, но, возможно, я делаю что-то не так, поскольку использую React.

Sylar
источник

Ответы:

170

Чтобы удалить элемент из массива, просто выполните:

array.splice(index, 1);

В твоем случае:

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
В моем случае это было: array.splice(array, 1);Спасибо
Сайлар
array.splice(array, 1);? Думаю, вам нужно его отредактировать .. Вы должны использовать разные переменные ...
Район,
61
При использовании React обычно следует избегать прямого изменения состояния. Вы должны создать новый массив и использовать setState().
iaretiga
2
В этом случае я рекомендую использовать Array.from (this.state.items) вместо оператора распространения. Это потому, что Array.from специально предназначен для этого использования.
Francisco Hodge,
2
Небольшое предложение, добавьте проверку «index! == -1» перед объединением массива, чтобы предотвратить нежелательное удаление.
RoboBear 07
205

При использовании React никогда не следует напрямую изменять состояние. Если объект (или Array, который тоже является объектом) изменяется, вы должны создать новую копию.

Другие предлагали использовать Array.prototype.splice(), но этот метод изменяет массив, поэтому его лучше не использовать splice()с React.

Самый простой в использовании Array.prototype.filter()для создания нового массива:

removePeople(e) {
    this.setState({people: this.state.people.filter(function(person) { 
        return person !== e.target.value 
    })});
}
iaretiga
источник
42
Да, это декларативный способ. Альтернативный метод с использованием функций prevState и arrow:this.setState(prevState => ({ people: prevState.people.filter(person => person !== e.target.value) }));
Джош Морел
9
Это должен быть принятый ответ в соответствии с идиомой React о том, что состояние никогда не изменяется.
lux
9
или используя индекс:this.state.people.filter((_, i) => i !== index)
mb21
2
есть неизменяемый срез и изменяемый срез
Кассиан
Проблема с этим ответом заключается в том, что если у вас есть несколько человек с одинаковыми именами, вы удалите их все. Использование индекса безопаснее в случаях, когда у вас могут быть
обманщики
40

Вот небольшой вариант ответа Александра Петрова с использованием ES6

removePeople(e) {
    let filteredArray = this.state.people.filter(item => item !== e.target.value)
    this.setState({people: filteredArray});
}
Дмитрий
источник
17

Используйте .spliceдля удаления элемента из массива. При использовании delete, индексы массива не будут изменены, но значение конкретного индекса будетundefined

Метод splice () изменяет содержимое массива, удаляя существующие элементы и / или добавляя новые элементы.

Синтаксис: 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);

Редактировать:

Как указал Джастин-Грант , как правило, никогда не изменяйте this.stateнапрямую, поскольку setState()последующий вызов может заменить произведенную вами мутацию. Относитесь this.stateк нему как к неизменному.

Альтернативой является создание копий объектов в this.stateи управление копиями, назначение их обратно с помощью setState(). Array#mapи Array#filterт. д. могут быть использованы.

this.setState({people: this.state.people.filter(item => item !== e.target.value);});
вискоза
источник
3
Убедитесь, что вы не используете splice или какой-либо метод, который напрямую изменяет вашу переменную состояния. Вместо этого вы захотите сделать копию массива, удалить элемент из копии, а затем передать копию в setState. В других ответах есть подробности о том, как это сделать.
Джастин Грант
12

Простой способ удалить элемент из массива состояний в React:

когда какие-либо данные удаляются из базы данных и обновляют список без вызова API, когда вы передаете удаленный идентификатор этой функции, и эта функция удаляет удаленные, записанные из списка

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
источник
1
Можете ли вы объяснить, чем это отличается от 8 других ответов на этот вопрос трехлетней давности? Из отзыва
Wai Ha Lee
в приведенном выше коде он воссоздает новый массив данных, но пропускает "deletePostId" этот идентификатор
ANKIT-DETROJA
использованиеitem.post_id !== deletePostId
Nimish goel
3

В некоторых ответах упоминалось использование «splice», которое, как сказал Ченс Смит, изменило массив. Я бы посоветовал вам использовать вызов метода «slice» (документ для «slice» здесь), который делает копию исходного массива.

Артур Чен
источник
3

Это очень просто: сначала вы определяете ценность

state = {
  checked_Array: []
}

Сейчас,

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
источник
1

Вы забыли использовать setState. Пример:

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

Но лучше использовать, filterпотому что он не мутирует массив. Пример:

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 doc для получения дополнительной информации

Gibbs
источник