Skip to main content

Як оновити елемент масиву у стані?

Головна ідея

У React стан повинен бути іммутабельним - не можна змінювати масив напряму (push, splice, присвоєння за index).

Замість цього потрібно створити новий масив з потрібними змінами і передати його в setState.


Приклад 1. Оновлення елемента за індексом

javascript
function App() { const [numbers, setNumbers] = useState([10, 20, 30]); const updateSecond = () => { setNumbers(prev => prev.map((num, i) => (i === 1 ? num + 5 : num)) ); }; return ( <div> <p>{numbers.join(", ")}</p> <button onClick={updateSecond}>Змінити другий елемент</button> </div> ); }

map() створює новий масив Ми змінюємо тільки той елемент, де i === 1 Решта залишаються без змін

Результат:

javascript
[10, 20, 30][10, 25, 30]

Приклад 2. Оновлення за умовою (наприклад, за id)

Дуже часто в стані зберігаються об'єкти:

javascript
const [users, setUsers] = useState([ { id: 1, name: "Alex", active: false }, { id: 2, name: "Tim", active: true }, ]);

Хочеш оновити конкретного користувача:

javascript
const toggleActive = (id) => { setUsers(prev => prev.map(user => user.id === id ? { ...user, active: !user.active } : user ) ); };

Що відбувається:

  • map() створює новий масив
  • якщо id збігається -> створюємо новий об'єкт (іммутабельно)
  • інакше повертаємо старий об'єкт

Приклад 3. Оновлення за індексом (варіант з копією масиву)

Можна зробити вручну:

javascript
const [items, setItems] = useState(["яблуко", "банан", "вишня"]); const changeBanana = () => { const copy = [...items]; // створюємо копію copy[1] = "манго"; // змінюємо елемент у копії setItems(copy); // оновлюємо стан };

Ніколи не роби так:

javascript
items[1] = "манго"; // мутує масив setItems(items); // React не помітить змін

Приклад 4. Оновлення вкладеного масиву в об'єкті

javascript
const [cart, setCart] = useState({ items: [ { id: 1, name: "Сорочка", qty: 1 }, { id: 2, name: "Штани", qty: 2 }, ], }); const incrementQty = (id) => { setCart(prev => ({ ...prev, items: prev.items.map(item => item.id === id ? { ...item, qty: item.qty + 1 } : item ), })); };

Тут:

  • ми копіюємо об'єкт cart (...prev)
  • всередині оновлюємо масив items іммутабельно через map()

5. Коли використовувати який спосіб

ЗавданняПідхід
Змінити за індексомmap() або копія з [...arr]
Змінити за idmap() з умовою
Оновити вкладений об'єктКопіювати і зовнішній, і внутрішній рівні
Додати елемент[...arr, newItem]
Видалити елементarr.filter(...)

Підсумок

Що не можна робитиЩо потрібно робити
array[index] = valuesetArray(prev => prev.map(...))
array.push(value)setArray(prev => [...prev, value])
array.splice(i,1)setArray(prev => prev.filter(...))
array.sort()setArray(prev => [...prev].sort(...))

Запам'ятай

Ніколи не мутуй масив стану напряму. Завжди створюй новий масив або об'єкт. React порівнює посилання, а не вміст. Використовуй map(), filter(), slice(), spread (...).

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.