React: Component Hàm so với Component Lớp - Cuộc Cách Mạng Hay Nâng Cấp Thực Tế?
Xin chào các nhà phát triển React! ☕️ Bạn có còn nhớ những ngày vật lộn với this.setState() và các phương thức vòng đời trong component lớp không? Bất chợt nào, component hàm với những Hooks lấp lánh xuất hiện, thế giới React đã thay đổi...
Thời xưa, có một component lớp...
Trong thời đại cổ xưa của React (chỉ vài năm trước 🙈), component lớp là lựa chọn duy nhất để xây dựng giao diện người dùng phức tạp. Chúng trông giống như thế này:
class DemTuSo extends React.Component {
constructor(props) {
super(props);
this.state = { giaTri: 0 };
// Đừng quên bind this, nếu không trình xử lý sự kiện sẽ bị "mất trí nhớ"
this.xuLyClick = this.xuLyClick.bind(this);
}
xuLyClick() {
this.setState({ giaTri: this.state.giaTri + 1 });
}
componentDidMount() {
console.log("Tôi đã được sinh ra!");
}
componentDidUpdate() {
console.log("Tôi đã thay đổi!");
}
componentWillUnmount() {
console.log("Tôi sắp ra đi...");
}
render() {
return (
<div>
<p>Số lần nhấp: {this.state.giaTri}</p>
<button onClick={this.xuLyClick}>Nhấp vào đây</button>
</div>
);
}
}
Nhìn đoạn mã này, có phải trong đầu bạn có một đàn thỏ đang nhảy nhót không? Đúng vậy, component lớp thực sự khá phức tạp, đặc biệt khi bạn cần xử lý vấn đề this, các phương thức vòng đời, cập nhật trạng thái...
Sau đó, component hàm với Hooks đã đứng ở vị trí trung tâm
Năm 2019, React 16.8 mang đến Hooks, và bỗng dưng, những component hàm đơn giản của chúng ta đã có siêu năng lực! Bây giờ bộ đếm tương tự trông như thế này:
function BoDemHienDai() {
const [giaTri, setGiaTri] = useState(0);
// Một useEffect xử lý cả ba phương thức vòng đời
useEffect(() => {
console.log("Tôi đã được sinh ra!");
return () => {
console.log("Tôi sắp ra đi...");
};
}, []);
useEffect(() => {
console.log("Tôi đã thay đổi!");
}, [giaTri]);
return (
<div>
<p>Số lần nhấp: {giaTri}</p>
<button onClick={() => setGiaTri(giaTri + 1)}>Nhấp vào đây</button>
</div>
);
}
Ồ... có phải cảm thấy mã nguồn bỗng trở nên gọn gàng hơn không? Không còn this, không còn ràng buộc phức tạp, các phương thức vòng đời cũng được gom lại.
Thực tế, chúng khác nhau ở điểm nào?
Thật sự, component hàm và component lớp về mặt **chức năng** gần như không có sự khác biệt - component hàm làm được gì, component lớp cũng làm được; component lớp làm được gì, component hàm (thông qua Hooks) cũng làm được.
Giống như hai nhà hàng cùng thực đơn, một bên là trang trí kiểu Trung Quốc truyền thống, bên kia là phong cách hiện đại tối giản. Món ăn ngon như nhau, nhưng trải nghiệm khác nhau.
1. Khác biệt về cú pháp: Chào từ biệt this
Ưu điểm rõ ràng nhất của component hàm là từ biệt từ khóa this. Trong JavaScript, hướng của this thường khiến các nhà phát triển đau đầu. Còn nhớ lỗi kỳ lạ khi quên bind trình xử lý sự kiện không? Với component hàm, những vấn đề đó tan biến như sương sớm.
2. Tổ chức mã: Chào từ biệt sự phân tán của vòng đời
Trong component lớp, logic liên quan thường bị phân tán vào các phương thức vòng đời khác nhau:
componentDidMount() {
// Lấy dữ liệu
}
componentDidUpdate(prevProps) {
if (prevProps.id !== this.props.id) {
// Lấy lại dữ liệu
}
}
componentWillUnmount() {
// Hủy yêu cầu
}
Trong khi đó, trong component hàm, logic liên quan có thể được gom lại:
useEffect(() => {
// Lấy dữ liệu
return () => {
// Hủy yêu cầu
};
}, [id]); // Chạy lại khi id thay đổi
Cách này giúp mã nguồn gắn kết hơn, dễ hiểu và bảo trì hơn.
3. Hiệu suất: Ưu thế của ứng viên hạng nhẹ
Component hàm thường nhẹ hơn component lớp, mã biên dịch nhỏ hơn, đó là tin tốt cho các ứng dụng quan tâm đến hiệu suất và thời gian tải. Ngoài ra, đội ngũ React cũng gợi ý rằng tối ưu hóa trong tương lai có thể nhắm nhiều hơn vào component hàm.
Vậy, component lớp có bị đào thải không?
Hãy yên tâm, đội ngũ React đã tuyên bố rõ ràng: **họ không có kế loại bỏ component lớp**. Bởi vì vô số dự án và thư viện đều sử dụng component lớp, việc loại bỏ bỗng dưng sẽ gây ra hỗn loạn quá lớn.
Tuy nhiên, hướng tương lai của React rất rõ ràng - component hàm và Hooks là nhân vật chính. Các tính năng và tối ưu hóa mới rất có thể sẽ ưu tiên component hàm. Giống như Windows 7 vẫn có thể dùng được, nhưng sự chú ý của Microsoft rõ ràng đang hướng đến Windows 11.
Lời khuyên thực tế: Làm thế nào để lựa chọn?
Nếu bạn là React mới bắt đầu hoặc đang bắt đầu một dự án mới, câu trả lời rất đơn giản: **chọn component hàm và Hooks**. Chúng đại diện cho tương lai của React, cú pháp đơn giản hơn, khái niệm thống nhất hơn.
Nếu bạn đang bảo trì dự án sử dụng component lớp, không cần phải viết lại ngay lập tức - điều này thường không thông minh. Có thể áp dụng chiến lược tiến bộ:
- Tính năng mới sử dụng component hàm
- Viết lại các component lớp đơn giản thành component hàm
- Component lớp phức tạp có thể xem xét sau cùng
Kết luận: Vẻ đẹp của sự giản đơn
Thú vị là, quá trình tiến hóa của React có phần giống như "trở về với bản chất". Nó bắt đầu từ lập trình hàm đơn giản, trải qua giai đoạn phức tạp của component lớp, rồi thông qua Hooks lại trở về sự giản đơn và tinh tế của lập trình hàm.
Đây là con đường phát triển phần mềm phổ biến - phức tạp không phải lúc nào cũng tốt, đôi khi, sự đơn giản sau khi suy nghĩ kỹ mới thực sự là cấp độ cao. Đây cũng là lý do tại sao nhiều nhà phát hiện thấy, sử dụng component hàm và Hooks không chỉ theo xu hướng, mà còn thực sự giảm gánh nhận thức và nâng cao năng suất trong quá trình lập trình thực tế.
Vì vậy, dù bạn là fan cứng của component lớp hay người mới yêu thích component hàm, điều quan trọng là hiểu sự khác biệt và giống nhau, chọn cách phù hợp với dự án và đội nhóm của mình. Bởi lẽ, công cụ dù tốt đến đâu cũng chỉ để giúp chúng ta xây dựng trải nghiệm người dùng tuyệt vời hơn, chứ không phải trở thành mục tiêu chính.