Những khái niệm cơ bản trong ReactJS cho người mới bắt đầu (Phần 2)
Bài đăng này đã không được cập nhật trong 5 năm
Xin chào tất cả mọi người! Trong bài viết trước, mình đã giới thiệu với các bạn về những khái niệm cơ bản nhất trong ReactJS như là: Component, JSX, Props, State. Các bạn có thể xem lại bài viết tại đây. Và để tiếp nối chủ đề này thì hôm nay mình sẽ giới thiệu những khái niệm quan trọng không kém khác trong ReactJS
Handling Events
Handling Events dùng để xử lý sử kiện trong React, nó cũng tương tự như handling event trên DOM Element, tuy nhiên có 1 số điểm khác nhau về cách sử dụng. Để mọi người dễ hình dung thì chúng ta cùng nhau xem qua 1 ví dụ sau:
import React, { Component } from 'react';
export default class App extends Component {
handleAlertText() {
alert('Hello World');
}
render() {
return(
<button onClick={this.handleAlertText}>Click me</button>
)
}
}
Ở ví dụ trên khi ta nhấn vào button Click me
thì sẽ hiện ra thông báo 'Hello World', ở đây có 1 sự kiện là handleAlertText
và ta đã gán nó vào button thông qua onClick. Khác với DOM Element là truyền vào onClick 1 string thì ở React ta truyền vào 1 JSX. Đó chính là 1 điểm khác biệt cơ bản giữa handling event trong React với DOM Element. Ngoài ra thì có 1 điểm mà mọi người cũng cần phải chú ý đó là quy tắc đặt tên các sự kiện trong React phải tuân thủ theo kiểu camelCase không được đặt theo dạng lowercase
Về vấn đề sử dụng this
trong handling event thì khi ta sử dụng this
trong handle event thì mặc định React sẽ không hiểu this
đấy là gì và sẽ báo lỗi Undefined. Để có thể sử dụng this
thì ta có 2 cách:
- Cách 1: Gán context cho
this
bằng hàmconstructor
:
import React, {Component} from 'react';
export default class App extends Component {
constructor(props){
super(props)
this.state = {
content: "Hello World"
}
this.handleAlertText = this.handleAlertText.bind(this) // gán context cho this
}
handleAlertText() {
alert(this.state.content);
}
render() {
<button onClick={this.handleAlertText}>Click me</button>
}
}
- Cách 2: Sử dụng Arrow function:
...
handleAlertText = () => {
this.setState({content: "Hello World123"});
alert(this.state.content);
}
...
Conditional Rendering
Conditional Rendering hoạt động tương tự với Conditional trong Javascript. Trong React thường sử dụng javascript operator như là if..else
để tạo các phần tử đại diện cho trạng thái hiện tại. Tức là với mỗi trạng thái khác nhau thì react sẽ tự động render ra cho chúng ta những Component tương ứng. Lấy ví dụ:
import React, { Component } from 'react';
class App extends Component {
render(){
if (this.props.show) {
return(<p>Hello World</p>)
}
return(<p>This content was hidden</p>)
}
}
export default App;
Đầu tiên, ta sẽ tạo ra 1 Component App, nhiệm vụ của nó là render ra 1 thẻ p
có nội dung tùy thuộc vào điều kiện this.props.show
trả về là true
hay false
.
ReactDOM.render(<App show={false} />, document.getElementById('root'));
Sau đó, ta sẽ truyền thuộc tính show
có giá trị là true
hoặc false
thông qua việc gọi Component App. Ở trường hợp trên, show
có giá trị là false
nên màn hình sẽ hiển thị kết quả là "The content was hidden"
Ngoài ra, trong React còn có thể dùng các biến để lưu trữ Component. Điều này giúp ta render một phần của Component trong khi những phần còn lại không hề thay đổi. Ví dụ:
import React, { Component } from 'react';
export default class App extends Component {
constructor(props){
super(props)
this.state = {
show: false,
}
}
handleToggle = () => {
this.setState({
show: !this.state.show
})
}
render() {
const contentElm = this.state.show
? <p>Hello World</p>
: <p>Content hidden</p>
return(
<div>
<button onClick={this.handleToggle}>Show/Hide</button>
{contentElm}
</div>
)
}
}
Ở đây mình có sử dụng cú pháp Ternary operation (toán tử 3 ngôi) thay thế cho if...else
để conditional rendering trở nên ngắn gọn và đơn giản hơn.
Lists and Keys
Trong React, List và Key được dùng để render nhiều Component khác nhau. Key là 1 thuộc tính giúp React xác định item nào được thêm mới, thay đổi hay gỡ bỏ khi chúng ta render nhiều item cùng 1 lúc.
Giá trị của Key phải là duy nhất để phân biệt 1 item với các item khác. Đối với những trường hợp giá trị của item không đổi trong mỗi lần render thì ta gắn index
của item để làm Key, tuy nhiên thường thì giá trị của item là thay đổi liên tục cho nên cách tốt nhất là ta lấy id của data để làm Key.
1 ví dụ về trường hợp data thay đổi và gắn index
làm key:
import React, { Component } from 'react';
function Row(props) {
return <div>{props.value}</div>;
}
class App extends Component {
constructor(props) {
super(props);
this.state = {
arr: [3,2,1],
lastAddedItem: 3,
}
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
let item = this.state.lastAddedItem + 1;
this.setState({
arr: [item].concat(this.state.arr),
lastAddedItem: item,
})
}
render() {
return (
<div>
<div>{this.state.arr.map((value, index) => <Row value={value} key={index} />)}</div>
<button onClick={this.handleClick}>Click</button>
</div>
);
}
}
- Trong lần render đầu tiên React sẽ render ra 1 list Component như sau:
- Sau khi click vào button
Click
:
Khi click vào button Click
thì React sẽ so sánh key hiện tại với key của các Row trước, nó nhận thấy key của các Row trước là không đổi nhưng giá trị value thì lại thay đổi, vì vậy nó sẽ phải update value của các Row đã render, còn Row với key="3"
chưa có nên nó sẽ khởi tạo mới.
Ta cùng xem xét trường hợp khi thay đổi key bằng value
:
<div>{this.state.arr.map(value => <Row value={value} key={value} />)}</div>
Như mọi người thấy, sau khi click button Click
thì React nó sẽ nhận ra rằng các key của các Row đã render lần trước có các value không đổi vì vậy nó sẽ giữ nguyên và chỉ render ra Row có key={4}
.
Rõ ràng, ở ví dụ trên trong trường hợp gắn value làm key thì performance đã được cải thiện đáng kể phải không nào Thực tế, sau này khi tham gia 1 dự án thật thì chắc chắn mọi người sẽ phải làm quen với ESLint - 1 công cụ giúp coding convention của chúng ta trở nên tối ưu nhất, trong ESLint có 1 rule đó là no-array-index-key
, và lúc này chắc chắn các bạn sẽ phải thay thế key cũ là index
bằng 1 key mới nào đó nếu như không muốn code của mình bị báo lỗi ESLint đỏ lòm =))
Kết luận
Hy vọng sau bài viết này mọi người đã có thể điều khiển được việc render trong React theo ý muốn, từ đó có thể tự mình xây dựng những app đơn giản. Các bạn có thể tham khảo thêm tại đây
All rights reserved