События

Последнее обновление: 01.04.2022

Обработка событий элементов в React во многом похожа на обработку событий элементов DOM с помощью обычного JavaScript. В то же время есть небольшие отличия:

  • События в React используют camelCase (в стандартном html "onclick", в React - "onClick")

  • В JSX в обработчик события передается функция компонента, а не строка

В React можно применять разные способы определения и вызова событий. Возьмем простейшую задачу - обработка нажатия кнопки.

События в функциональных компонентах

Использование событий в функциональных компонентах несколько проще. Так, перепишем предыдущий компонент в функциональном стиле:

function ClickButton(props) {
            
    function press(){
        alert("Hello React!")
    }
    return <button onClick={press}>Click</button>;
}

Здесь используется событие нажатия кнопки, которое задается через атрибут onClick (не onclick).

Этому атрибуту в качестве обработчика события передавалась функция press, которая определена в функции компонента. И при нажатии на кнопку будет вызываться функция press, которая с помощью функции alert отображает окно с некоторым уведомлением.

Использование функционального компонента:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>METANIT.COM</title>
</head>
<body>
    <div id="app"></div>
       
    <script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
    <script type="text/babel">
        function ClickButton(props) {
            
            function press(){
               alert("Hello React!")
            }
            return <button onClick={press}>Click</button>;
        }
        ReactDOM.createRoot(
            document.getElementById("app")
        )
        .render(
            <ClickButton />
        );
    </script>
</body>
</html>
Обновление состояния и события в React

События в компонентах-классах

При определении событий в классах-компонентах распространенный подход заключается в установке привязки события в конструкторе компонента:

class ClickButton extends React.Component {
             
	constructor(props) {
		super(props);
		this.press = this.press.bind(this);
	}
	press(){
		console.log(this);
		alert("Hello React!")
	}
	render() {
		return <button onClick={this.press}>Click</button>;
	}
}

Главная сложность при использовании событий в компонентах-классах - это работа с ключевым словом this, которое указывает на текущий объект, в данном случае компонент. По умолчанию в функцию обработчика не передается текущий объект, поэтому this будет иметь значение undefined. И ни к каким свойствам и методам компонента через this мы обратиться не сможем. И чтобы в метод press корректно передавалась ссылка на текущий объект через this, в конструкторе класса прописывается вызов:

this.press = this.press.bind(this);

И также стоит отметить, что при определении конструктора компонента в нем должен вызываться конструктор базового класса, в который передается объект props.

Использование класса-компонента на веб-странице аналогично:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>METANIT.COM</title>
</head>
<body>
    <div id="app"></div>
      
    <script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
    <script type="text/babel">
        class ClickButton extends React.Component {
             
           constructor(props) {
               super(props);
                 
               this.press = this.press.bind(this);
           }
           press(){
			   console.log(this);
               alert("Hello React!")
           }
           render() {
               return <button onClick={this.press}>Click</button>;
           }
       }
         
       ReactDOM.createRoot(
            document.getElementById("app")
        )
        .render(
            <ClickButton />
        );
    </script>
</body>
</html>

Однако есть и другие способы определения и вызова события. Например, определение обработчика в виде публичного поля компонента, которое указывает на стрелочную функцию.

class ClickButton extends React.Component {
             
	press = () => {
		console.log(this);
		alert("Hello React!")
	}
	render() {
		return <button onClick={this.press}>Click</button>;
	}
}

Либо мы можем определить функцию обработчика события как обычный метод класса, а вызывать с помощью стрелочной функции:

class ClickButton extends React.Component {
             
	press(){
		console.log(this);
		alert("Hello React!");
	}
	render() {
		return <button onClick={() => this.press()}>Click</button>;
	}
}

Однако в случае с использованием стрелочной функции есть вероятность столкнуться с проблемой производительности, если функция обработчика передается через свойства props вложенным компонентам. Так как обработчик события будет создаваться каждый раз заново при каждом рендеринге компонента, что может привести к дополнительному повторному рендерингу вложенных компонентов, без которого можно было бы обойтись. Поэтому использование конструктора является более предпочтительной практикой.

Получение информации о событии

React использует концепцию SyntheticEvent - специальных объектов, которые представляют собой обертки для объектов событий, передаваемых в функцию события. И используя такой объект, мы можем получить в обработчике события всю информацию о событии:

function ClickButton(props) {
             
    function press(e){
        console.log(e); // выводим информацию о событии
        alert("Hello React!")
    }

    return <button onClick={press}>Click</button>;
}

Параметр e - это и есть информация о событии, которая передается в обработчик системой и которую мы можем использовать при обработке.

Аналогичный пример для класса-компонента:

class ClickButton extends React.Component {
             
	constructor(props) {
		super(props);
		this.press = this.press.bind(this);
	}
	press(e){
		console.log(e);	// выводим информацию о событии
		alert("Hello React!")
	}
	render() {
		return <button onClick={this.press}>Click</button>;
	}
}

Передача параметров в обработчик события

Если необходимо передать в обработчик события некоторые аргументы, то в этом случае можно вызвать обработчик через стрелочную функцию:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>METANIT.COM</title>
</head>
<body>
    <div id="app"></div>
        
    <script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
    <script type="text/babel">
        function PrintButton(props) {
             
            function print(name, age){
				console.log(`Name ${name}  Age: ${age}`);
           }

            return <div> 
                        <button onClick={() => print("Bob", 23)}>Print Bob</button>
                        <button onClick={() => print("Tom", 36)}>Print Tom</button>
                    </div>;
        }
        ReactDOM.createRoot(
            document.getElementById("app")
        )
        .render(
            <PrintButton />
        );
    </script>
</body>
</html>
Передача параметров в обработчик события в React

Аналогичный пример для класса-компонента:

class PrintButton extends React.Component {
             
    constructor(props) {
        super(props);
                 
        this.print = this.print.bind(this);
    }
    print(name, age){
		console.log(`Name ${name}  Age: ${age}`);
    }
    render() {
        return <div> 
			<button onClick={() => this.print("Bob", 23)}>Print Bob</button>
			<button onClick={() => this.print("Tom", 36)}>Print Tom</button>
		</div>;
    }
}
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850