Components
Function và Class Components
Components hiểu theo một nghĩa đơn giản là các thành phần UI riêng biệt, độc lập giúp bạn có thể chia nhỏ giao diện ra thành từng phần để dễ quản lý, phát triển. Đồng thời, chúng ta cũng có thể dễ dàng tái sử dụng các component này ở những nơi khác nhau.
Về mặt khái niệm thì components giống như các hàm Javascript. Chúng có thể nhận các tham số đầu vào thông qua "props" sẽ được giải thích ở phần sau và trả về một element, cái mà sẽ được vẽ lên màn hình ứng dụng web, mobile...
Để định nghĩa một function component chúng ta có thể xem ví dụ sau
function App() {
return (
<div className="App">
<ListExpenses/>
</div>
);
}
Đây là 1 component có tên là App, nó sẽ trả về 1 React element là ListExpenses, đây cũng là 1 component được gọi từ component App. Điều này cũng đã nói ở phần đầu, components có thể gọi lẫn nhau để xây dựng nên một UI hoàn chỉnh hơn và có thể tái sử dụng.
Thường chúng ta gọi là "function components" bởi vì chúng được viết như một JavaScript function
Chúng ta cũng có thể sử dụng ES6 class để định nghĩa 1 component như sau:
class App extends React.Component {
render() {
return (
<div className="App">
<ListExpenses/>
</div>
);
}
}
Cả 2 cách trên đều hoạt động như nhau, nhưng cách sử dụng function components có vẻ đơn giản và dễ sử dụng hơn
Render một Component
Với việc xây dựng được một React element ở trên là App, chúng ta có thể tiến hành render nó trên trình duyệt web như sau:
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
Khi được biên dịch, React sẽ tạo ra một element có tên là root và vẽ tất cả các component mà chúng ta đã định nghĩa trong đó.
Props
Khái niệm và cách gửi Props
Giống như một function Javascript thông thường chúng ta sẽ sử dụng các tham số để làm giá trị input bên trong function đó. Tương ứng với việc sử dụng component như là một javascript function, nó cũng sẽ nhận tham số đầu vào để cần xử lý các dữ liệu bên trong, tham số này được định nghĩa với tên là props. Nó có thể nhận 1 giá trị hoặc 1 object theo cách chúng ta định nghĩa.
Điều khác biệt là props mang thuộc tính là read-only, chúng ta chỉ có nhận giá trị mà props cung cấp bên trong thân hàm chứ không thể thay đổi ngược lại giá trị của nó. Nó còn được gọi theo 1 cái tên là 1 pure function.
Để gửi dữ liệu từ component này đến component khác thông qua props chúng ta có thể khai báo như ví dụ sau:
const data = [
{
id: "e1",
title: "Car Insurance",
amount: 294.67,
date: new Date(2021, 2, 28),
},
{
id: "e2",
title: "New Home",
amount: 20000,
date: new Date(2021, 5, 12),
},
];
function App() {
return (
<div className="App">
<ListExpenses data={data} />
</div>
);
}
Ở đây ta quan sát thấy component là ListExpenses ta muốn truyền dữ liệu cho component này để sử dụng ta có thể khai báo 1 tên là "data" và truyền giá trị là 1 object data vào bên trong nó như cú pháp trong ví dụ. Chúng ta có thể truyền nhiều loại dữ liệu khác nếu chúng ta muốn, ví dụ như tiếp tục name="abc", gender="male"...
Nhận dữ liệu từ Props
Để nhận dữ liệu thông qua props, khi xây dựng 1 component cần phải thêm giá trị tham số đầu vào là props. Chúng ta có thể hình dung qua ví dụ bên dưới:
const ListExpenses = (props) => {
const data = props.data;
return (
<div>
<ExpenseItem item={data[0]} />
<ExpenseItem item={data[1]} />
<ExpenseItem item={data[2]} />
<ExpenseItem item={data[3]} />
</div>
);
};
Và để nhận dữ liệu "data" ở phía trên, chúng ta chỉ cần gọi props.data là dễ dàng nhận được dữ liệu đã truyền cho component ListExpenses.
Quan sát thêm ví dụ này, chúng ta cũng dễ dàng thấy được mỗi giá trị từ props.data lại được truyền cho các component ExpenseItem. Và ở mỗi component ExpenseItem để nhận dữ liệu này thì chỉ cần gọi props.item
Tổng hợp
Dựa vào các kiến thức của component và props chúng ta có thể tiến hành xây dựng 1 UI như bên dưới, để hiển thị danh sách các chi phí. Trong mỗi mục là ngày thực hiện, tên chi phí và tổng số tiền. Giao diện có thể hình dung như bên dưới
Các phần cơ bản của soure code:
- App.js
import "./App.css";
import ListExpenses from "./components/ListExpenses";
const data = [
{
id: "e1",
title: "Car Insurance",
amount: 294.67,
date: new Date(2021, 2, 28),
},
{
id: "e2",
title: "New Home",
amount: 20000,
date: new Date(2021, 5, 12),
},
{
id: "e3",
title: "Football",
amount: 50,
date: new Date(2021, 7, 16),
},
{
id: "e4",
title: "Covid vacxin",
amount: 80,
date: new Date(2021, 1, 22),
},
];
function App() {
return (
<div className="App">
<ListExpenses data={data} />
</div>
);
}
export default App;
- ListExpenses.js
import React from "react";
import ExpenseItem from "./ExpenseItem";
const ListExpenses = (props) => {
const data = props.data;
return (
<div>
<ExpenseItem item={data[0]} />
<ExpenseItem item={data[1]} />
<ExpenseItem item={data[2]} />
<ExpenseItem item={data[3]} />
</div>
);
};
export default ListExpenses;
- ExpenseItem.js
import React from "react";
import ExpenseDate from "./ExpenseDate";
import "./ExpenseItem.css";
const ExpenseItem = (props) => {
const date = props.item.date;
const title = props.item.title;
const amount = props.item.amount;
return (
<div className="expense-item">
<ExpenseDate date={date} />
<div className="expense-item__description">
<h2>{title}</h2>
<div className="expense-item__price">{amount}</div>
</div>
</div>
);
};
export default ExpenseItem;
- ExpenseDate.js
import React from "react";
import "./ExpenseDate.css";
const ExpenseDate = (props) => {
const day = props.date.toLocaleString("en-US", { day: "2-digit" });
const month = props.date.toLocaleString("en-US", { month: "long" });
const year = props.date.getFullYear();
return (
<div className="expense-date">
<div className="expense-date__moth">{month}</div>
<div className="expense-date__year">{year}</div>
<div className="expense-date__day">{day}</div>
</div>
);
};
export default ExpenseDate;