Обработчики как пропсы
В настоящем приложении кнопки находятся в отдельных компонентах: кнопка «Голосовать» — в BandCard. Но то, что делает голос, относится к App, у которого есть вся программа фестиваля, а скоро будет и число голосов. Поэтому App пишет обработчик и передаёт его каждой карточке как проп. В App.jsx:
function handleVote(name) {
console.log(`Ваш голос: ${name}`);
}
return (
<ul>
{bands.map((band) => (
<BandCard key={band.id} band={band} onVote={handleVote} />
))}
</ul>
);Функция — такое же значение, как любое другое, поэтому она может быть пропсом, как текст или число. BandCard читает её из пропсов и вызывает, когда нажимают на её кнопку. В BandCard.jsx:
export default function BandCard({ band, onVote }) {
return (
<li className="card">
<h2>{band.name}</h2>
<button onClick={() => onVote(band.name)}>Голосовать</button>
</li>
);
}При клике кнопка запускает стрелочную функцию, та вызывает onVote("Совиный хор"), а onVote — это handleVote из App. Так клик в карточке запускает код в App. Карточке не нужно знать, что делает голос. Она только сообщает, что кто-то проголосовал за её группу.
Проп называется onVote, как onClick у кнопки: on и то, что произошло. А функция, которую передаёт App, называется handleVote. Это снова соглашения: пропсы для обработчиков называют onSomething, а функции-обработчики — handleSomething. Но onVote — обычный проп. React не вызывает его сам, как вызывает onClick у кнопки; его вызывает BandCard.
Типичная ошибка: onClick={onVote} в карточке. Тогда React вызовет onVote с объектом события вместо названия, и App выведет Ваш голос: [object Object].
Задание
- 1
В
AppнапишитеhandleVote(name), которая выводитВаш голос: Совиный хор— с полученным названием, — и передайте её каждомуBandCardкак пропonVote. ВBandCard.jsxпрочитайтеonVoteиз пропсов и вызовите его с названием группы, когда нажимают «Голосовать». - 2
Сделайте то же для кнопки «Подробности» с пропом
onDetails. Карточка вызывает его со всем объектомband, аhandleDetails(band)вAppвыводитСовиный хор: Лесная сцена, 16:00.