Содержание
Обработчик onClick позволяет передать компоненту функцию, которая будет выполнена при его нажатии. Вызовите e.preventDefault(), чтобы предотвратить нативное поведение по умолчанию, например, отправку формы.
const App = () => { const sendMessage = (e) => { e.preventDefault(); alert('hi'); } return ( <button onClick={sendMessage}> Send message </button> ) }
Обработка событий onClick в функциональных компонентах
Обработчики событий - это функции, которые выполняются при наступлении определенного события. Например, с их помощью можно отправить сообщение после того, как пользователь нажмет на кнопку.
Возможно, вы уже знакомы с обработчиками событий из обычного HTML и JavaScript. Обработчики событий в React очень похожи.
HTML предоставляет нам такие обработчики событий, как onclick, onchange, onfocus и многие другие. Мы можем использовать их, добавляя к элементу HTML в качестве атрибута.
<button onclick="sendMessage();"> Отправить </button>.
То же самое мы можем сделать и в React. В большинстве случаев обработчики событий в React имеют те же названия, что и в HTML, но пишутся в camelCase. Обработчики, приведенные выше, в React будут переведены как onClick, onChange и onFocus.
<button onClick={sendMessage}> Send </button>
Как видите, все не совсем так, как в примере HTML. Во-первых, фигурные скобки ({}) заменяют двойные кавычки ("), используемые в HTML.
Фигурные скобки используются в синтаксисе JSX для отделения разметки от JavaScript.
Все, что находится внутри скобок, оценивается как JavaScript. Все, что находится за пределами скобок, - это разметка, которая будет выведена на экран.
Для более полной картины давайте посмотрим, как может выглядеть готовый компонент.
const App = () => { const sendMessage = () => { alert('hi'); } return ( <button onClick={sendMessage}> Send message </button> ); }
Здесь мы видим, почему нам нужно было заключить sendMessage в фигурные скобки. Мы определяем функцию sendMessage как переменную в начале компонента.
Распространенной ошибкой здесь является вызов функции сразу же (как в примере HTML).
<button onClick={sendMessage()}>
Вместо того чтобы вызывать функцию при нажатии на кнопку, она будет вызываться при каждом рендеринге компонента.
Нам нужно передать только саму функцию, не вызывая ее.
<button onClick={sendMessage}>
Кроме того, вы можете встроить саму функцию.
<button onClick={() => sendMessage()}>
Обратите внимание, как мы вызываем sendMessage во встроенной функции. Мы делаем это потому, что она является частью встроенной функции, которую мы не вызываем сразу.
Синтетические события React
Как вы, возможно, уже слышали, в React есть виртуальный DOM, который представляет собой слой абстракции, используемый React для оптимизации рендеринга и некоторых специфических для браузера функций.
Это значит, что хотя код, который мы пишем в React, похож на HTML, это не совсем то же самое.
Я написал статью о том, как именно это работает. Вы можете ознакомиться с ней здесь.
Так же как React добавляет абстракцию поверх DOM, он также добавляет слой абстракции для событий. События React называются синтетическими событиями.
Синтетические события - это обертка вокруг событий, которая улучшает производительность и нормализует события, чтобы они выглядели одинаково во всех браузерах.
Такие события передаются в обработчики событий, например onClick. Мы можем использовать его для доступа к атрибуту value элемента button.
const App = () => {
const sendMessage = (e) => {
console.log('value', e.target.value); // output: “value somevalue”
alert('hi');
}
return (
<button value="somevalue" onClick={sendMessage}> Send message </button>
)
}
React preventDefault()
Доступ к атрибуту value обычно осуществляется при работе с текстовым вводом, а не в сочетании с onClick.
В приложениях React чаще всего встречается следующее:
const sendMessage = (e) => { e.preventDefault(); alert('hi'); }
Мы вызываем функцию preventDefault в обработчике события, которое предоставляет синтетическое событие. Уже из названия понятно, что она делает: предотвращает выполнение события по умолчанию.
Чтобы понять это немного лучше, нам нужно знать, как ведут себя по умолчанию различные элементы HTML.
Если элемент button находится внутри элемента form, то по умолчанию форма будет отправлена.
Это хорошо, когда в HTML-формах все равно была только одна кнопка, но что, если вы хотите выполнить только код функции onClick без отправки формы?
В React мы обычно решаем эту проблему, помещая e.preventDefault() в начало обработчика события.
В качестве альтернативы, вы можете решить эту проблему, изменив атрибут type кнопки:
<button type="button">Нажмите на меня! </button>.
Элементы формы по умолчанию ведут себя еще хуже: Они обновляют всю страницу после события onSubmit - это не то, что вы хотели бы видеть в одностраничном приложении.
Обработка событий onClick в компонентах класса
В предыдущем разделе я сосредоточился только на функциональных компонентах. Хотя это самый простой способ написания компонентов в React, вы все равно будете время от времени сталкиваться с компонентами, написанными как классы JavaScript.
Итак, давайте рассмотрим предыдущий пример в виде класса React:
class App extends React.Component {
sendMessage = (e) => {
e.preventDefault();
console.log('value', e.target.value); // output: “value somevalue”
alert('hi');
};
render() {
return (
<button value="somevalue" onClick={this.sendMessage}>
Send message
</button>
);
}
}
Как видите, способ обработки событий onClick в классах React такой же, как и в функциональных компонентах. Функция sendMessage теперь является частью класса App, поэтому мы обращаемся к ней через this.
Если вам интересно, почему я определил sendMessage как переменную, а не как метод класса: Это сделано для того, чтобы сохранить область видимости класса внутри функции, что практически означает, что я смогу вызвать this.setState внутри функции.