← Назад к вопросам
Как подписаться на событие нажатия на кнопку?
2.0 Middle🔥 181 комментариев
#JavaScript Core
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Подписка на событие click
Есть несколько способов подписаться на событие нажатия кнопки в JavaScript и React.
1. Ванильный JavaScript
// Способ 1: inline обработчик
<button onclick="handleClick()">Click me</button>
// Способ 2: addEventListener (рекомендуется)
const button = document.getElementById('my-button');
button.addEventListener('click', function(event) {
console.log('Button clicked!', event);
});
// Способ 3: Присваивание функции
const button = document.querySelector('button');
button.onclick = function() {
console.log('Clicked');
};
// Способ 4: Стрелочная функция (предпочтительно)
button.addEventListener('click', (event) => {
console.log('Button clicked:', event.target);
});
2. React - основной способ
// Функциональный компонент - рекомендуется
export function Button() {
const handleClick = (event) => {
event.preventDefault();
console.log('Button clicked!');
};
return <button onClick={handleClick}>Click me</button>;
}
// Или через стрелочную функцию прямо в JSX
export function Button() {
return (
<button onClick={() => console.log('Clicked')}>
Click me
</button>
);
}
3. React с параметрами
// Передача данных в обработчик
export function Button() {
const handleClick = (id, event) => {
console.log('Button ID:', id);
console.log('Event:', event);
};
return (
<button onClick={(e) => handleClick(123, e)}>
Click me
</button>
);
}
// Или с bind
export function Button() {
const handleClick = function(id) {
console.log('ID:', id);
};
return (
<button onClick={handleClick.bind(this, 123)}>
Click me
</button>
);
}
4. Получение информации о событии
export function Button() {
const handleClick = (event) => {
console.log('Target:', event.target); // Элемент
console.log('Type:', event.type); // 'click'
console.log('Timestamp:', event.timeStamp); // Время
console.log('Coordinates:', {
x: event.clientX,
y: event.clientY
});
// Остановить распространение события
event.stopPropagation();
// Отменить поведение по умолчанию
event.preventDefault();
};
return <button onClick={handleClick}>Click me</button>;
}
5. useCallback для оптимизации
import { useCallback } from 'react';
export function ButtonWithCallback() {
const handleClick = useCallback((event) => {
console.log('Clicked!');
}, []); // Зависимости
return <button onClick={handleClick}>Click me</button>;
}
// С параметрами
export function ButtonWithParams({ itemId }) {
const handleClick = useCallback((e) => {
console.log('Item ID:', itemId);
}, [itemId]);
return <button onClick={handleClick}>Click {itemId}</button>;
}
6. Обработчик в пользовательском компоненте
// Компонент Button с prop
interface MyButtonProps {
onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void;
children: React.ReactNode;
}
export function MyButton({ onClick, children }: MyButtonProps) {
return (
<button onClick={onClick} className="btn">
{children}
</button>
);
}
// Использование
export function Parent() {
const handleClick = (event) => {
console.log('Clicked');
};
return <MyButton onClick={handleClick}>Click me</MyButton>;
}
7. Несколько обработчиков на один элемент
export function Button() {
const handleClick = () => {
console.log('First handler');
};
const handleSecondClick = () => {
console.log('Second handler');
};
const handleMultiple = (event) => {
handleClick();
handleSecondClick();
};
return (
<button onClick={handleMultiple}>
Click me
</button>
);
}
8. Типизированный обработчик в TypeScript
import { MouseEvent } from 'react';
interface ButtonProps {
onClick?: (event: MouseEvent<HTMLButtonElement>) => void;
}
export function Button({ onClick }: ButtonProps) {
const handleClick: React.MouseEventHandler<HTMLButtonElement> = (event) => {
event.preventDefault();
onClick?.(event);
};
return <button onClick={handleClick}>Click me</button>;
}
9. Delegation - обработка кликов на нескольких элементах
export function List() {
const handleListClick = (event: React.MouseEvent) => {
const target = event.target as HTMLElement;
if (target.tagName === 'BUTTON') {
const itemId = target.dataset.id;
console.log('Clicked item:', itemId);
}
};
return (
<div onClick={handleListClick}>
<button data-id="1">Item 1</button>
<button data-id="2">Item 2</button>
<button data-id="3">Item 3</button>
</div>
);
}
Лучшие практики
// ХОРОШО: useCallback с правильными зависимостями
import { useCallback, useState } from 'react';
export function Counter() {
const [count, setCount] = useState(0);
const handleClick = useCallback(() => {
setCount(c => c + 1); // Функциональное обновление
}, []);
return <button onClick={handleClick}>Count: {count}</button>;
}
// ПЛОХО: Функция на каждый рендер
export function BadCounter() {
const [count, setCount] = useState(0);
// Новая функция при каждом рендере - неэффективно
return (
<button onClick={() => setCount(count + 1)}>
Count: {count}
</button>
);
}
Рекомендуемый подход в React: используй onClick в JSX с useCallback для оптимизации и правильной типизацией в TypeScript.