Xử lý sự kiện (Event) trong ReactJS
Trong bài học này tôi sẽ hướng dẫn bạn "Làm sao để sử dụng Event (sự kiện) trong ReactJS". Cũng không có nhiều khác biệt khi bạn sử dụng các event trong ReactJS so với sử dụng các event trong Javascript.
- Trong Javascript bạn sẽ xử lý sự kiện trong một hàm, còn trong React bạn sẽ xử lý sự kiện trong một phương thức của Component.
1. ReactJS Events
React là một thư viện dựa trên Javascript, về cơ bản không có nhiều khác biệt trong cách xử lý sự kiện giữa ReactJS và Javascript. Với Javascript, khi sự kiện xẩy ra một hàm sẽ được gọi để thực thi. Nhưng với React, khi sự kiện xẩy ra, sẽ có một phương thức của Component được gọi.
OK, trước hết hãy xem một ví dụ đơn giản:
onClick-example.html
class CurrentTime extends React.Component {
constructor(props) {
super(props);
var now = new Date();
this.state = {
currentTime: now.toString()
};
}
// A method of CurrentTime component
refreshCurrentTime() {
var now = new Date();
this.setState({ currentTime: now.toString() });
}
render() {
return (
<div>
<h4>Current Time:</h4>
<p>{this.state.currentTime}</p>
<button onClick={() => this.refreshCurrentTime()}>
Refresh Current Time
</button>
</div>
);
}
}
// Render
ReactDOM.render(<CurrentTime />, document.getElementById("currenttime1"));
onClick-example.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ReactJS Event</title>
<script src="https://unpkg.com/react@16.4.2/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16.4.2/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script>
<style>
#currenttime1 {
border:1px solid blue;
padding: 5px;
margin-top: 20px;
}
</style>
</head>
<body>
<h3>ReactJS Event: onClick</h3>
<div id="currenttime1"></div>
<script src="onClick-example.jsx" type="text/babel"></script>
</body>
</html>
Arrow Function
Với cú pháp Javascript ES6 bạn có thể tạo một arrow function (Hàm mũi tên), rất ngắn gọn và dễ hiểu:
** arrow function **
// Normal function with parameters
var myfunc = function(param1, param2) {
// Statements
};
// Arrow function with parameters.
var arrfunc = (param1, param2) => {
// Statements
};
// Normal function without paramters.
var myfunc2 = function( ) {
// Statements
};
// Arrow function without parameters.
var arrfunc2 = ( ) => {
// Statements
};
// If function have only one statement.
var arrfunc2 = ( ) => singleStatement;
onClick, onChange,..
onClick phải gọi đến một hàm Javascript, nó không thể gọi trực tiếp đến một phương thức của Component. Vì vậy onClick nên gọi đến một hàm nặc danh (anonymous), và bên trong hàm nặc danh này bạn có thể gọi đến phương thức của Component:
Arrow function với tham số event:
// A method of Component with event parameter.
refreshCurrentTime(event) {
var now = new Date();
this.setState({ currentTime: now.toString() });
}
render() {
return (
<div>
<h4>Current Time:</h4>
<p>{this.state.currentTime}</p>
<button onClick={(event) => this.refreshCurrentTime(event)}>
Refresh Current Time
</button>
</div>
);
}
Với Javascript ES6 bạn cũng có thể gọi đến phương thức của Component theo cách sau:
.jsx
// A method of this Component.
refreshCurrentTime(event) {
var now = new Date();
this.setState({ currentTime: now.toString() });
}
render() {
return (
<div>
<h4>Current Time:</h4>
<p>{this.state.currentTime}</p>
<button onClick={this.refreshCurrentTime.bind(this,event)}>
Refresh Current Time
</button>
</div>
);
}
Hoặc:
onClick-example3.jsx
class CurrentTime extends React.Component {
constructor(props) {
super(props);
var now = new Date();
this.state = {
currentTime: now.toString()
};
// (***)
this.refreshCurrentTime = this.refreshCurrentTime.bind(this);
}
// A method of this Component
refreshCurrentTime( ) {
var now = new Date();
this.setState({ currentTime: now.toString() });
}
render() {
return (
<div>
<h4>Current Time:</h4>
<p>{this.state.currentTime}</p>
<button onClick={this.refreshCurrentTime}>
Refresh Current Time
</button>
</div>
);
}
}
// Render
ReactDOM.render(<CurrentTime />, document.getElementById("currenttime1"));
2. Event của Component con
Một sự kiện xẩy ra tại Component con, nhưng bạn muốn gọi đến một phương thức tại Componen cha, dưới đây là một ví dụ như thế.
childEvent-example.jsx
// <Child> with 1 attribute: myClickHandler
// <Child myClickHandler=.. />
class Child extends React.Component {
render() {
return (
<div className="child">
<h4>Child</h4>
<button onClick={this.props.myClickHandler}>Click me!</button>
</div>
);
}
}
class Parent extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
}
myMethodOfParent() {
this.setState((prevState, props) => {
return {
count: prevState.count + 1
};
});
}
render() {
return (
<div className="parent">
<h3>(Parent) Clicked: {this.state.count} </h3>
<Child myClickHandler={() => this.myMethodOfParent()} />
</div>
);
}
}
// Render
ReactDOM.render(<Parent />, document.getElementById("placeholder1"));
childEvent-example.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ReactJS Event</title>
<script src="https://unpkg.com/react@16.4.2/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16.4.2/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script>
<style>
.parent {
border:1px solid #d9ebe8;
padding: 5px;
margin-top: 20px;
}
.child {
width:150px;
border:1px solid #8cb0aa;
margin: 5px;
padding: 5px;
}
</style>
</head>
<body>
<h3>The child's event calls to parent's method</h3>
<div id="placeholder1"></div>
<script src="childEvent-example.jsx" type="text/babel"></script>
</body>
</html>
3. Một ví dụ phức tạp
OK, và bây giờ là một ví dụ phức tạp hơn, nó yêu cầu bạn thông thạo nhiều kiến thức trong ReactJS, chẳng hạn Lists, Props, State, Event..
Các kiến thức trong ReactJS mà bạn cần biết:
complex-example.jsx
// <OrderDetail> with 4 attributes:
// productName, price, quantity, addHandler
class OrderDetail extends React.Component {
render() {
return (
<div className="order-detail">
<h4>{this.props.productName}</h4>
<p>Price: {this.props.price} USD</p>
<p>Quantity: {this.props.quantity}</p>
<p>
<button onClick={this.props.addHandler}>+</button>
</p>
</div>
);
}
}
class Order extends React.Component {
constructor(props) {
super(props);
this.state = {
amount: 0,
details: [
{ id: 1, productName: "IPhone X", price: 900, quantity: 0 },
{ id: 2, productName: "Samsung S9", price: 800, quantity: 0 },
{ id: 3, productName: "Nokia 8", price: 650, quantity: 0 }
]
};
}
updateOrder(index) {
this.setState((prevState, props) => {
console.log(this.state.details);
var newQty = prevState.details[index].quantity + 1;
this.state.details[index].quantity = newQty;
this.state.amount = prevState.amount + 1 * prevState.details[index].price;
return {
amount: this.state.amount,
details: this.state.details
};
});
}
render() {
// Array of <OrderDetail ../>
var detailTags = this.state.details.map((e, index) => (
<OrderDetail
key={e.id}
addHandler={() => this.updateOrder(index)}
productName={e.productName}
price={e.price}
quantity={e.quantity}
/>
));
return (
<div className="order">
{detailTags}
<div className="clear" />
<p className="total">Total: <b>{this.state.amount} USD</b></p>
</div>
);
}
}
// Render
ReactDOM.render(<Order />, document.getElementById("order1"));
complex-example.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ReactJS Event</title>
<script src="https://unpkg.com/react@16.4.2/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16.4.2/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script>
<style>
.order {
border:1px solid #d9ebe8;
padding: 5px;
margin-top: 20px;
}
.order-detail {
float : left;
width:150px;
border:1px solid #8cb0aa;
margin: 5px;
padding: 5px;
}
.clear {
clear: both;
}
.total {
margin: 5px;
}
</style>
</head>
<body>
<h3>Complex Example (Event, List, Props, State)</h3>
<div id="order1"></div>
<script src="complex-example.jsx" type="text/babel"></script>
</body>
</html>
Các hướng dẫn ReactJS
- Hướng dẫn và ví dụ ReactJS props và state
- Xử lý sự kiện (Event) trong ReactJS
- Hướng dẫn và ví dụ ReactJS Component API
- Các phương thức trong vòng đời của ReactJS Component
- Hướng dẫn và ví dụ ReactJS Refs
- Hướng dẫn và ví dụ ReactJS Lists và Keys
- Hướng dẫn và ví dụ ReactJS Form
- Tìm hiểu về ReactJS Router với ví dụ tại phía Client
- Giới thiệu về Redux
- Ví dụ đơn giản với React và Redux tại phía Client
- Hướng dẫn sử dụng React-Transition-Group API
- Bắt đầu nhanh với ReactJS trên môi trường NodeJS
- Tìm hiểu về ReactJS Router với một ví dụ cơ bản (NodeJS)
- Ví dụ React-Transition-Group Transition (NodeJS)
- Ví dụ React-Transition-Group CSSTransition (NodeJS)
- Giới thiệu về ReactJS
- Cài đặt React Plugin cho trình soạn thảo Atom
- Tạo một HTTP Server đơn giản với NodeJS
- Bắt đầu nhanh với ReactJS
Show More