Các thủ thuật với JSX trong React (phần 1)
Ở bài học trước chúng ta đã biết cú pháp JSX có thể được áp dụng cho nhiều thư viện JavaScript UI khác nhau không riêng React. Nhưng để thu hẹp phạm vi, chúng ta hãy cùng tìm hiểu những thủ thuật làm việc với JSX trong thư viện cụ thể React.
CSS class
Attribute class
của HTML khi chuyển qua JSX phải viết là className
. Tuy vậy nhóm phát triển React đang có dự định sẽ đổi lại sử dụng class
, chưa biết cụ thể khi nào, nhưng ở thời điểm hiện tại thì chúng ta vẫn nên dùng className
trong JSX nha.
Mã HTML
<div class="alert alert-success"> Thao tác đã thành công! </div>
Mã JSX
<div className="alert alert-success"> Thao tác đã thành công! </div>
CSS style
Attribute style
của HTML nhận vào một string (thật ra attribute nào của HTML mà chẳng nhận vào string 😁), còn style
của JSX yêu cầu một JSON object.
Mã HTML
<div style="color: red, border: 1px solid red, font-size: 2rem"> Thông báo khẩn! </div>
Mã JSX
const cssProps = { color: 'red', border: '1px solid red', 'font-size': '2rem', }; <div style={cssProps}> Thông báo khẩn! </div>
Mã JSX rút gọn, nhét trực tiếp object vào attribute style
.
<div style={{ color: 'red', border: '1px solid red', 'font-size': '2rem', }} > Thông báo khẩn </div>
Hãy chú ý 02 (hai) cặp ngoặc móc, cặp ngoài cùng là cú pháp truyền biến vào attribute của JSX, cặp bên trong là cú pháp JSON object. Nhớ đừng bỏ sót.
Render có điều kiện (Conditional rendering)
Dùng toán tử ba ngôi (Tenary operator)
Render nhánh này hoặc nhánh kia, tùy điều kiện:
<div> { condition ? <strong>True</strong> : <em>False</em> } </div>
Render gì đó hoặc không gì hết, tùy điều kiện:
<div> { condition ? <strong>True</strong> : null } </div>
Dùng kỹ thuật “đoản mạch” (Short-circuit)
Nếu condition
là true thì render, không thì thôi:
<div> { condition && <strong>True</strong> } </div>
Nếu condition
là false thì render, không thì thôi:
<div> { condition || <strong>True – Cách 1</strong> } { !condition && <strong>True – Cách 2, chú ý dấu ! phủ định</strong> } </div>
Dùng cấu trúc if-else
và switch-case
Kỹ thuật này dành cho những điều kiện render phức tạp, rẽ nhánh nhiều.
let message = null; if (condition == 0) message = <strong>Neutral</strong>; else if (condition < 0) message = <strong>Negative</strong>; else if (condition > 0) message = <strong>Positive</strong>; return ( <div>{message}</div> );
let message; switch (condition) { case 1: message = <strong>First</strong>; break; case 2: message = <strong>Second</strong>; break; case 3: message = <strong>Third</strong>; break; default: message = null; } return ( <div>{message}</div> );
Render với vòng lặp
Hàm map()
của Array
Hàm map()
của Array xử lý từng item của một mảng rồi trả về một mảng khác. Còn JSX lại hỗ trợ render một mảng-các-JSX sẵn rồi, chúng ta sẽ lợi dụng đặc điểm đó:
const virtues = ['Nhân', 'Lễ', 'Nghĩa', 'Trí', 'Tín']; const jsxItems = virtues.map(v => <li key={v}>{v}</li>); return ( <ul>{jsxItems}</ul> );
Kết quả sau khi render:
<ul> <li>Nhân</li> <li>Lễ</li> <li>Nghĩa</li> <li>Trí</li> <li>Tín</li> </ul>
Vòng lặp
Tuy hàm map()
phổ biến hơn, nhưng trong một số trường hợp phức tạp chỉ có vòng lặp truyền thống mới giải quyết được.
const jsxItems = []; for (let i = 1; i <= 5; ++i) { jsxItems.push(<li key={i}>{i}</li>); } return ( <ul>{jsxItems}</ul> );
Kết quả sau khi render:
<ul> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> </ul>
Không thể tin được chỉ in từ 1 tới 5 thôi mà phải phức tạp như vậy đúng không nào! Đó là lý do vì sao hàm map()
vẫn được ưa chuộng hơn.
Thuộc tính “key” để làm gì?
Những phần tử JSX được tạo ra bên trong vòng lặp phải có thuộc tính “key” để cơ chế của ReactDOM dễ nhận biết phần tử nào đã được thêm/xóa sau mỗi lần cập nhật giao diện. Do đó giá trị của thuộc tính “key” phải mang tính đặc trưng của mỗi item.
Render HTML Entity từ một string
JSX hỗ trợ HTML Entity nếu được viết trực tiếp, nhưng nếu mã Entity được truyền trong một string thì JSX sẽ không render.
function EntityDisplay(props) { return <span>{props.message} ♦</span> } <EntityDisplay message="Tú lơ khơ ♠ ♣ ♥" />
Kết quả in ra sẽ như sau, chỉ có Entity hình Diamond được viết trực tiếp mới hiển thị được.
Tú lơ khơ ♠ ♣ ♥ ♦
Nếu muốn JSX render được HTML Entity thì phải sử dụng hàm String.fromCharCode()
.
<EntityDisplay message={`Tú lơ khơ ${String.fromCharCode(9824)} ${String.fromCharCode(9827)} ${String.fromCharCode(9829)}`} />
Nhìn kinh khủng quá phải không, hãy thử viết ngắn một chút cho đỡ sợ nào:
const entity = String.fromCharCode; <EntityDisplay message={`Tú lơ khơ ${entity(9824)} ${entity(9827)} ${entity(9829)}`} />
Các bạn hãy tham khảo danh sách HTML Entity để biết mã số của mỗi ký tự.
Truyền props của component cha cho component con
Khi làm việc với Higher-order Component, chúng ta thường xuyên phải truyền gần như tất cả props của component cha cho component con.
Truyền tất cả props, dùng cú pháp “bung lụa” (Spread syntax):
function Parent(props) { return <Child {...props} /> }
Truyền một phần props, dựa trên kỹ thuật Destructuring Assignment:
function Parent(props) { const { size, className, ...otherProps } = props; return ( <Child size={size} className={className}> <GrandChild {...otherProps} /> </Child> ); }
(Còn nữa)
Tag:react
Facebook Comments