Объекты в состоянии
Значения, которые относятся друг к другу, могут жить в одном состоянии — в виде объекта. У заказа билетов есть тип и количество:
const [ticket, setTicket] = useState({ type: "Выходные", count: 1 });Страница читает его как любой объект: {ticket.count} × {ticket.type} показывает 1 × Выходные. Менять его нужно по тому же правилу, что и массивы: не меняйте объект из состояния (ticket.count = 2 ничего нового не покажет), а создайте новый. Spread копирует объект, а свойство, записанное после него, заменяет свойство копии:
const newTicket = { ...ticket, count: 2 };В newTicket есть всё, что было в ticket, включая type, а count равно 2. Без spread вызов setTicket({ count: 2 }) потерял бы type: сеттер заменяет всё состояние целиком, он не объединяет новый объект со старым.
Как и новые массивы, новый объект, созданный из старого, записывается в функции-обновителе. Здесь она добавляет 1 к количеству. Одна деталь: когда стрелочная функция возвращает объект, объект нужно взять в круглые скобки:
function handleMore() {
setTicket((ticket) => ({ ...ticket, count: ticket.count + 1 }));
}Без них фигурные скобки стали бы телом функции, как в (ticket) => { return …; }, а ...ticket в теле — ошибка: красное сообщение под предпросмотром говорит Unexpected token, expected ",", и приложение не запускается. Круглые скобки превращают фигурные в объект, который стрелочная функция и возвращает.
Две переменные состояния, type и count, тоже подошли бы. Объект удобен, когда значения описывают одну вещь и меняются вместе, как заказ билетов.
Задание
- 1
Сделайте
ticketсостоянием с тем же начальным объектом. Кнопка «Ещё один» добавляет 1 к количеству — с новым объектом, созданным с помощью spread. - 2
Сделайте так, чтобы кнопки «Пятница», «Суббота» и «Выходные» меняли тип билета и сохраняли его количество.