Cấu tạo của một component trong React và cách tạo ra nó
Ứng dụng web sử dụng React được thiết kế theo kiến trúc component-based, nên cách tạo ra một component là bài học thực hành đầu tiên (sau một mớ lý thuyết). Trong React có 2 loại component:
Component hàm (Functional component)
Là một hàm JavaScript bình thường nhưng giá trị return là một object React Element. Object này được tạo ra bởi hàm React.createElement
hoặc React.cloneElement
.
Không dùng JSX:
import React from 'react'; // Hàm truyền thống function EmailField() { return React.createElement( 'input', { type: 'email' } ); } // Hàm mũi tên (Arrow function) const SubscriptionForm = () => React.createElement( 'form', null, React.createElement(EmailField) );
Có dùng JSX:
import React from 'react'; // Hàm truyền thống function EmailField() { return (<input type="email"/>); } // Hàm mũi tên (Arrow function) const SubscriptionForm = () => ( <form> <EmailField /> </form> );
Component lớp (Class component)
Là một class JavaScript thừa kế từ React.Component
hoặc React.PureComponent
hay một Class component khác. Class này phải implement hàm render()
có giá trị return là một object React Element, nội dung hàm render()
này cũng giống như Functional component.
import { Component, PureComponent } from 'react'; class EmailField extends Component { render() { return (<input type="email" />); } } class SubscriptionForm extends PureComponent { render() { return ( <form> <EmailField /> </form> ); } }
Đặt tên cho component
Tên của React Component phải viết hoa dạng Pascal case. Đoạn mã sau sẽ bị lỗi ở dòng số 3:
function numberInput() { return (<input type="number"); } <numberInput />
Đoạn mã sau sẽ chạy ổn:
function numberInput() { return (<input type="number"); } let NumberInput = numberInput; <NumberInput />
Truyền tham số từ ngoài vào cho React Component
Tham số của React Component được gọi là «property». Những ngôn ngữ markup như XML, HTML gọi tham số truyền vào là «attribute». Dịch sang tiếng Việt cả 2 đều là “thuộc tính” hết. Trong các tài liệu tiếng Anh, «property» thường dùng trong ngữ cảnh ngôn ngữ JavaScript, còn «attribute» thường dùng với ngôn ngữ markup.
Attribute của JSX lại có thể nhận vào bất kỳ kiểu dữ liệu nào mà một biến JavaScript có thể chứa, nhưng attribute của HTML nói riêng và XML nói chung chỉ có một kiểu dữ liệu chuỗi (string). Khi truyền dữ liệu kiểu string cho React Component thì phải có cặp ngoặc nháy "..."
, nếu truyền kiểu dữ liệu khác, hoặc truyền biến, thì phải đặt trong cặp ngoặc móc {...}
. JSX attribute phải được viết hoa ở dạng camel case.
function SalaryInput () { const holderText = 'Enter your salary'; return ( <NumberInput label="Salary" placeholder={holderText} readonly={false} decimalDigits={2} /> ); }
Truyền kiểu dữ liệu nào vào thẻ HTML thì cũng được coi là string:
<input type="number" value={500} /> // Cũng giống như <input type="number" value="500" />
Tham số kiểu boolean có giá trị true
có thể được viết rút gọn, nhưng giá trị false
thì phải viết ở dạng đầy đủ:
<NumberInput readonly /> // Cũng giống như <NumberInput readonly={true} />
Nhận tham số từ bên trong React Component
Functional component
Component hàm nhận được một tham số là một object gồm các key và value được truyền vào từ JSX.
const NumberInput = (props) => { console.log(props); // In ra { label: "Salary", placeholder: "Enter your salary", readonly: false, decimalDigits: 2 } return (...); };
Class component
Component lớp nhận được một class property tên là props
. Truy cập đến nó bằng cú pháp this.props
.
class NumberInput extends React.Component { render() { console.log(this.props); // In ra { label: "Salary", placeholder: "Enter your salary", readonly: false, decimalDigits: 2 } return (...); } }
Phân tách tham số (Argument destructuring)
Object Destructuring là một cú pháp có từ JavaScript ES6, chúng ta có thể tận dụng nó để lấy ra những property mà mình muốn sử dụng:
function NumberInput(props) { const { placeholder: holder, readonly=false } = props; return ( <input placeholder={holder} readonly={readonly} /> ); } class NumberInput extends React.Component { render() { const { placeholder: holder, readonly=false } = this.props; return ( <input placeholder={holder} readonly={readonly} /> ); } }
Mặc dù ở ví dụ trên chúng ta đã dùng chức năng “default value” của destructuring để gán giá trị mặc định cho prop readonly
, nhưng cách làm này không được khuyến khích, thay vào đó hãy dùng kỹ thuật dưới đây.
Prop mặc định
React cho phép chúng ta đặt giá trị mặc định cho prop với defaultProps
, nếu nó không được truyền từ bên ngoài vào. Ưu điểm của cách này so với default value của destructuring là không cần phải khai báo nhiều lần mỗi khi cần destructure một prop.
function NumberInput(props) { const { placeholder: holder, readonly=false } = props; return ( <input placeholder={holder} readonly={readonly} /> ); } NumberInput.defaultProps = { readonly: false, decimalDigits: 4 } class NumberInput extends React.Component { static defaultProps = { readonly: false, decimalDigits: 4 }; render() { const { placeholder: holder, readonly=false } = this.props; return ( <input placeholder={holder} readonly={readonly} /> ); } }
Không được gán đè props
Props là tham số từ bên ngoài truyền vào cho component, nên React không cho phép gán đè giá trị khác cho props. Đoạn mã sau sẽ gây lỗi:
function NumberInput(props) { props.readonly = true; return (... ); }
Tag:react
Facebook Comments