Никаких изменений, всегда создавайте новые версии

Мутации текущего состояния не вызовут повторный рендеринг. Поэтому вам нужно установить состояние вновь созданного объекта или массива. Для этого есть разные способы. В документации React также упоминается, что состояние можно рассматривать как доступное только для чтения. Часто вам помогает синтаксис распространения.

Обновление объектов в состоянии — React || Обновление массивов в State — React

Синтаксис распространения

Вы можете использовать синтаксис расширения для массивов и объектов для создания копий значений.

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

const [alphabet, setAlphabet] = useState(['b', 'c', 'e']);

function setAtBeginning(letter = 'a'){
   setAlphabet([
    letter, 
    ...alphabet
   ]);
}

function setAtMiddle(letter = 'd', insertAt = 2){
   setAlphabet([
    ...alphabet.slice(0, insertAt)
    letter, 
    ...alphabet.slice(insertAt)
   ]);
}

function setAtEnd(letter = 'z'){
   setAlphabet([
    ...alphabet,
    letter
   ]);
}

Если вы хотите добавить или изменить значения объекта, вы также можете использовать синтаксис распространения для этого случая. Рассмотрите следующее состояние с держит объект любимой еды и где его взять.

const [favoriteFood, setFavoriteFood] = useState({
   name: 'Pizza',
   restaurant: 'Due Fratelli'
});

Поэтому, если мы хотим обновить только название ресторана и ничего больше, потому что мы как бы нашли новое место, куда можно пойти, мы можем использовать только синтаксис распространения.

setFavoriteFood({
  ...favoriteFood, 
  restaurant: 'Il Trullo'
});

Но обратите внимание, оператор спреда работает только на один уровень. Если у вас есть какие-либо уровни настройки глубже, вам нужно использовать оператор спреда и там.

Так, например, если мы хотим добавить местоположение ресторана как вложенный объект, синтаксис распространения работает по-другому. Но обо всем по порядку. Давайте посмотрим на начальное состояние с вложенным объектом.

const [favoriteFood, setFavoriteFood] = useState({
   name: 'Pizza',
   restaurant: {
    name: 'Due Fratelli',
    city: 'Munich'
   }
});

Теперь, если мы хотим снова обновить название ресторана, вам нужно использовать оператор спреда для каждого уровня.

setFavoriteFood({
   ...favoriteFood,
   restaurant: {
     ...favoriteFood.restaurant,
     name: 'Il Trullo'
   }
});