Какой предпочтительный способ изменить состояние React?

86

Скажем, у меня есть список простых объектов в моем this.state.list, который затем я могу использовать для отображения списка детей. Каков тогда правильный способ вставить объект в this.state.list?

Ниже приведен единственный способ, по которому он будет работать, потому что вы не можете напрямую мутировать this.state, как указано в документе.

this._list.push(newObject):
this.setState({list: this._list});

Это кажется мне уродливым. Есть ли лучший способ?

  • 0
    возможный дубликат корректной модификации массивов состояний в ReactJS , запрашивающий слияние
  • 0
    Все эти ответы о добавлении элемента в массив. Но как насчет удаления элемента из него? Или просто полностью сбросить массив на новый?
Теги:

4 ответа

148
Лучший ответ

concat возвращает новый массив, поэтому вы можете сделать

this.setState({list: this.state.list.concat([newObject])});

другой альтернативой является React помощник по неизменности

  var newState = React.addons.update(this.state, {
      list : {
        $push : [newObject]
      }
  });

  this.setState(newState);
  • 6
    concat принимает массив, поэтому вам понадобится this.state.list.concat([newObject]) .
  • 0
    @BenAlpert работает на меня в Chrome, вы говорите, что это нестандартное поведение?
Показать ещё 5 комментариев
39

setState() можно вызвать с помощью функции в качестве параметра:

this.setState((state) => ({ list: state.list.concat(newObj) }))

или в ES5:

this.setState(function(state) {
  return {
   list: state.list.concat(newObj)
  }
})
  • 0
    Интересно, реагирует ли на рендеринг только добавленный элемент или весь массив?
  • 2
    @Arian: React выполнит необходимые инструкции по мутации DOM, необходимые для визуализации только новых добавленных элементов. Конечно, учитывая, что вы недавно добавили элементы, не измените способ отображения предыдущих элементов.
Показать ещё 7 комментариев
14

Обновление 2016

С ES6 вы можете использовать:

this.setState({ list: [...this.state.list, ...newObject] });
  • 4
    ...[newObject] - это то же самое, что и newObject .
  • 1
    Это не будет работать для пакетных обновлений. Смотрите мой пример на stackoverflow.com/a/41445812/1998186 .
6

Из интерактивных документов (https://facebook.github.io/react/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous):

Поскольку this.props и this.state могут обновляться асинхронно, вы не должны полагаться на их значения для вычисления следующего состояния.

Итак, вы должны сделать это вместо:

this.setState((prevState) => ({
  contacts: prevState.contacts.concat([contact])
}));

Ещё вопросы

Сообщество Overcoder
Наверх
Меню